mirror of https://github.com/golang/go.git
internal/gcimporter: optimize dependency lookup
The old code based on packages.Visit traversed in a deterministic order, and didn't stop when it found its target (the 'return false' only prunes that subtree). This CL replaces it with a precomputation of the PkgPath-to-*Package mapping. The performance difference is small for this test but it nearly dominates on a larger input (e.g. k8s). Example code shouldn't steer users into asymptotic traps. Change-Id: I19f4fc2c25da3d2ae00090704df30a54d8516bf5 Reviewed-on: https://go-review.googlesource.com/c/tools/+/447958 gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Alan Donovan <adonovan@google.com> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
39c2fd8bff
commit
3c8152e28a
|
|
@ -89,6 +89,23 @@ func typecheck(t *testing.T, ppkg *packages.Package) {
|
|||
}
|
||||
// Inv: all files were successfully parsed.
|
||||
|
||||
// Build map of dependencies by package path.
|
||||
// (We don't compute this mapping for the entire
|
||||
// packages graph because it is not globally consistent.)
|
||||
depsByPkgPath := make(map[string]*packages.Package)
|
||||
{
|
||||
var visit func(*packages.Package)
|
||||
visit = func(pkg *packages.Package) {
|
||||
if depsByPkgPath[pkg.PkgPath] == nil {
|
||||
depsByPkgPath[pkg.PkgPath] = pkg
|
||||
for path := range pkg.Imports {
|
||||
visit(pkg.Imports[path])
|
||||
}
|
||||
}
|
||||
}
|
||||
visit(ppkg)
|
||||
}
|
||||
|
||||
// importer state
|
||||
var (
|
||||
insert func(p *types.Package, name string)
|
||||
|
|
@ -100,16 +117,8 @@ func typecheck(t *testing.T, ppkg *packages.Package) {
|
|||
return gcimporter.IImportShallow(fset, importMap, data, imp.PkgPath, insert)
|
||||
}
|
||||
insert = func(p *types.Package, name string) {
|
||||
// Hunt for p among the transitive dependencies (inefficient).
|
||||
var imp *packages.Package
|
||||
packages.Visit([]*packages.Package{ppkg}, func(q *packages.Package) bool {
|
||||
if q.PkgPath == p.Path() {
|
||||
imp = q
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}, nil)
|
||||
if imp == nil {
|
||||
imp, ok := depsByPkgPath[p.Path()]
|
||||
if !ok {
|
||||
t.Fatalf("can't find dependency: %q", p.Path())
|
||||
}
|
||||
imported, err := loadFromExportData(imp)
|
||||
|
|
|
|||
Loading…
Reference in New Issue