Skip to content

Commit 3c8152e

Browse files
committed
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 <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Alan Donovan <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent 39c2fd8 commit 3c8152e

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

internal/gcimporter/shallow_test.go

+19-10
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,23 @@ func typecheck(t *testing.T, ppkg *packages.Package) {
8989
}
9090
// Inv: all files were successfully parsed.
9191

92+
// Build map of dependencies by package path.
93+
// (We don't compute this mapping for the entire
94+
// packages graph because it is not globally consistent.)
95+
depsByPkgPath := make(map[string]*packages.Package)
96+
{
97+
var visit func(*packages.Package)
98+
visit = func(pkg *packages.Package) {
99+
if depsByPkgPath[pkg.PkgPath] == nil {
100+
depsByPkgPath[pkg.PkgPath] = pkg
101+
for path := range pkg.Imports {
102+
visit(pkg.Imports[path])
103+
}
104+
}
105+
}
106+
visit(ppkg)
107+
}
108+
92109
// importer state
93110
var (
94111
insert func(p *types.Package, name string)
@@ -100,16 +117,8 @@ func typecheck(t *testing.T, ppkg *packages.Package) {
100117
return gcimporter.IImportShallow(fset, importMap, data, imp.PkgPath, insert)
101118
}
102119
insert = func(p *types.Package, name string) {
103-
// Hunt for p among the transitive dependencies (inefficient).
104-
var imp *packages.Package
105-
packages.Visit([]*packages.Package{ppkg}, func(q *packages.Package) bool {
106-
if q.PkgPath == p.Path() {
107-
imp = q
108-
return false
109-
}
110-
return true
111-
}, nil)
112-
if imp == nil {
120+
imp, ok := depsByPkgPath[p.Path()]
121+
if !ok {
113122
t.Fatalf("can't find dependency: %q", p.Path())
114123
}
115124
imported, err := loadFromExportData(imp)

0 commit comments

Comments
 (0)