internal/lsp/completion: don't use Type.String for checking identity

Completion is very performance sensitive, and building a string to check
for *testing.F has a significant cost.

StructCompletion-8         20.7ms ±14%  16.8ms ± 1%  -18.59%  (p=0.000 n=10+10)
ImportCompletion-8         1.36ms ± 5%  1.05ms ±18%  -22.55%  (p=0.000 n=9+10)
SliceCompletion-8          23.5ms ± 2%  19.3ms ±18%  -17.85%  (p=0.000 n=7+10)
FuncDeepCompletion-8       17.6ms ± 2%  15.5ms ± 2%  -11.82%  (p=0.000 n=8+8)
CompletionFollowingEdit-8  81.2ms ± 8%  74.2ms ± 5%   -8.60%  (p=0.000 n=9+9)

For golang/go#53992
For golang/go#53798

Change-Id: Ia138cbadce142a424caabe8259bda05bcc536055
Reviewed-on: https://go-review.googlesource.com/c/tools/+/422906
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Findley 2022-08-13 15:02:08 -04:00
parent 5a26068387
commit 987de349f4
1 changed files with 14 additions and 1 deletions

View File

@ -1245,7 +1245,7 @@ func (c *completer) methodsAndFields(typ types.Type, addressable bool, imp *impo
c.methodSetCache[methodSetKey{typ, addressable}] = mset
}
if typ.String() == "*testing.F" && addressable {
if isStarTestingDotF(typ) && addressable {
// is that a sufficient test? (or is more care needed?)
if c.fuzz(typ, mset, imp, cb, c.snapshot.FileSet()) {
return
@ -1272,6 +1272,19 @@ func (c *completer) methodsAndFields(typ types.Type, addressable bool, imp *impo
})
}
// isStarTestingDotF reports whether typ is *testing.F.
func isStarTestingDotF(typ types.Type) bool {
ptr, _ := typ.(*types.Pointer)
if ptr == nil {
return false
}
named, _ := ptr.Elem().(*types.Named)
if named == nil {
return false
}
return named.Obj() != nil && named.Obj().Pkg().Path() == "testing" && named.Obj().Name() == "F"
}
// lexical finds completions in the lexical environment.
func (c *completer) lexical(ctx context.Context) error {
var (