[analyzer] Cache deserialized unlinked units, don't deserialize the same units over and over again

TL;DR: In the scenario outlined below this CL makes the analyzer use
~50MB less ram after initial analysis, answer the first implements query
~1.2 seconds (~25%) faster and use ~300MB less ram after the first
implements query.

Details:

The below measurements are taken with 8 folders from the sdk open that
overlaps: `pkg/analysis_server`, `pkg/analysis_server_client`,
`pkg/analyzer`, `pkg/analyzer_cli`, `pkg/analyzer_plugin`,
`pkg/analyzer_utilities`, `pkg/_fe_analyzer_shared`, `pkg/front_end`).

The query run is a find all implementations query for the class
`ToJsonable` in
`pkg/analysis_server/lib/lsp_protocol/protocol_special.dart`.

An initial run not shown here was made to let the analyzer cache results as needed.

BEFORE:

isAnalyzing is now done after 0:00:06.661205
heap 524.6MB of 546.8MB
Got answer to query in 0:00:05.285724
heap 943.8MB of 990.1MB

isAnalyzing is now done after 0:00:06.766694
heap 525.0MB of 547.0MB
Got answer to query in 0:00:04.932227
heap 941.9MB of 990.5MB

isAnalyzing is now done after 0:00:06.806875
heap 522.4MB of 547.6MB
Got answer to query in 0:00:05.227859
heap 941.9MB of 990.5MB

isAnalyzing is now done after 0:00:06.663847
heap 507.4MB of 550.0MB
Got answer to query in 0:00:05.107593
heap 941.9MB of 991.0MB

isAnalyzing is now done after 0:00:06.649731
heap 507.4MB of 549.8MB
Got answer to query in 0:00:05.055295
heap 941.9MB of 990.5MB


WITH CL:

isAnalyzing is now done after 0:00:06.575444
heap 461.7MB of 489.2MB
Got answer to query in 0:00:03.758280
heap 628.0MB of 671.6MB

isAnalyzing is now done after 0:00:06.630200
heap 471.2MB of 488.9MB
Got answer to query in 0:00:03.786806
heap 643.3MB of 671.6MB

isAnalyzing is now done after 0:00:06.437794
heap 465.0MB of 485.6MB
Got answer to query in 0:00:03.995996
heap 628.0MB of 671.3MB

isAnalyzing is now done after 0:00:06.706091
heap 457.4MB of 487.2MB
Got answer to query in 0:00:03.748728
heap 640.8MB of 671.1MB

isAnalyzing is now done after 0:00:06.610832
heap 467.7MB of 486.2MB
Got answer to query in 0:00:03.877194
heap 643.9MB of 671.1MB


Initial analysis:
No difference proven at 95.0% confidence

After initial analysis, heap, utilized:
Difference at 95.0% confidence
        -52.76 +/- 10.9161
        -10.1979% +/- 2.10996%
        (Student's t, pooled s = 7.48475)

After initial analysis, heap, capacity:
Difference at 95.0% confidence
        -60.82 +/- 2.29212
        -11.0937% +/- 0.418087%
        (Student's t, pooled s = 1.57162)

First implements query:
Difference at 95.0% confidence
        -1.28834 +/- 0.18012
        -25.1543% +/- 3.51677%
        (Student's t, pooled s = 0.123502)

After first implements query, heap, utilized:
Difference at 95.0% confidence
        -305.48 +/- 8.41655
        -32.4192% +/- 0.893211%
        (Student's t, pooled s = 5.77092)

After first implements query, heap, capacity:
Difference at 95.0% confidence
        -319.18 +/- 0.418906
        -32.2235% +/- 0.0422915%
        (Student's t, pooled s = 0.287228)

Change-Id: Ice2bd0e8c90285c2097afe2589d19f79762d3837
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/275201
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
9 files changed
tree: 041ede440ff5ab1a6d03738248a8446aff894757
  1. .dart_tool/
  2. .github/
  3. benchmarks/
  4. build/
  5. docs/
  6. pkg/
  7. runtime/
  8. samples/
  9. sdk/
  10. tests/
  11. third_party/
  12. tools/
  13. utils/
  14. .clang-format
  15. .gitattributes
  16. .gitconfig
  17. .gitignore
  18. .gn
  19. .mailmap
  20. .style.yapf
  21. .vpython
  22. AUTHORS
  23. BUILD.gn
  24. CHANGELOG.md
  25. codereview.settings
  26. CONTRIBUTING.md
  27. DEPS
  28. LICENSE
  29. OWNERS
  30. PATENT_GRANT
  31. PRESUBMIT.py
  32. README.dart-sdk
  33. README.md
  34. sdk_args.gni
  35. SECURITY.md
  36. WATCHLISTS
README.md

Dart

A client-optimized language for fast apps on any platform

Dart is:

  • Optimized for UI: Develop with a programming language specialized around the needs of user interface creation.

  • Productive: Make changes iteratively: use hot reload to see the result instantly in your running app.

  • Fast on all platforms: Compile to ARM & x64 machine code for mobile, desktop, and backend. Or compile to JavaScript for the web.

Dart's flexible compiler technology lets you run Dart code in different ways, depending on your target platform and goals:

  • Dart Native: For programs targeting devices (mobile, desktop, server, and more), Dart Native includes both a Dart VM with JIT (just-in-time) compilation and an AOT (ahead-of-time) compiler for producing machine code.

  • Dart Web: For programs targeting the web, Dart Web includes both a development time compiler (dartdevc) and a production time compiler (dart2js).

Dart platforms illustration

License & patents

Dart is free and open source.

See LICENSE and PATENT_GRANT.

Using Dart

Visit dart.dev to learn more about the language, tools, and to find codelabs.

Browse pub.dev for more packages and libraries contributed by the community and the Dart team.

Our API reference documentation is published at api.dart.dev, based on the stable release. (We also publish docs from our beta and dev channels, as well as from the primary development branch).

Building Dart

If you want to build Dart yourself, here is a guide to getting the source, preparing your machine to build the SDK, and building.

There are more documents on our wiki.

Contributing to Dart

The easiest way to contribute to Dart is to file issues.

You can also contribute patches, as described in Contributing.