You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
gopls/internal/lsp/cache: reduce importing in analysis
This CL is a substantial reorganization of the analysis driver to
ensure that export data is imported at most once per batch of packages
that are analyzed, instead of once per import edge. This greatly
reduces the amount of allocation and computation done during analysis.
In cache/analysis.go, Snapshot.Analyze (which now takes a set of
PackageIDs, instead of being called singly in a loop) constructs an
ephemeral DAG that mirrors the package graph, and then works in
parallel postorder over this graph doing analysis. It uses a single
FileSet for the whole batch of packages it creates. The subgraph
rooted at each node is effectively a types.Importer for that node,
as it represents the mapping from PackagePath to *types.Package.
We no longer bother with promises or invalidation. We rely on the fact
that the graph is relatively cheap to construct, cache hits are cheap
to process, and the whole process only occurs after an idle delay of
about a second.
Also:
- In internal/facts, optimize the fact decoder by using a callback.
Previously, it was spending a lot of time traversing the API of all
imports of a package to build a PackagePath-to-types.Package
mapping. For many packages in terraform-provider-aws this visits
over 1M objects (!!). But of course this is trivially computed from
the new representation.
- In internal/gcimporter, IImportShallow now uses a single callback to
get all the types.Package symbols from the client, potentially in
parallel (and that's what gopls does). The previous separation of
"create" and "populate" has gone away.
The analysis driver additionally exploits the getPackages callback to
efficiently read the package manifest of an export data file,
then abort with an error before proceeding to actually decode
the rest of the file.
With this change, we can process the internal/provider package of the
terraform-provider-aws repo in 20s cold, 4s hot. (Before, it would run
out of memory.)
$ go test -bench=InitialWorkspaceLoad/hashiform ./gopls/internal/regtest/bench
BenchmarkInitialWorkspaceLoad/hashiform-8 1 4014521793 ns/op 349570384 alloc_bytes 439230464 in_use_bytes 668992216 total_alloc_bytes
PASS
Fixesgolang/go#60621
Change-Id: Iadeb02f57eb19dcccb639857053b897a60e0a90e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/503195
Reviewed-by: Robert Findley <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Run-TryBot: Alan Donovan <[email protected]>
Reviewed-by: Alan Donovan <[email protected]>
0 commit comments