gopls/internal/lsp: optimize checks for ignored files
Optimize checking for ignored files to avoid unnecessary checks, and
only build prefixes once. Along the way, fix a bug where path segments
were not handled correctly in the ignore check. Encapsulate the check to
make this easy to test.
As a result, the DiagnoseChange/google-cloud-go benchmark improved ~5x
from ~1.5s to 300ms.
Also remove span.Dir, which tended to lead to unnecessary
filepath->span->filepath conversions. Inline it in the one place where
it was correct.
For golang/go#60089
Change-Id: Id24d05b504b43e6a6d9b77b5b578583e1351de31
Reviewed-on: https://go-review.googlesource.com/c/tools/+/494097
Reviewed-by: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
diff --git a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snapshot.go
index 6bd4be8..7e9a06f 100644
--- a/gopls/internal/lsp/cache/snapshot.go
+++ b/gopls/internal/lsp/cache/snapshot.go
@@ -185,6 +185,11 @@
// pkgIndex is an index of package IDs, for efficient storage of typerefs.
pkgIndex *typerefs.PackageIndex
+
+ // Only compute module prefixes once, as they are used with high frequency to
+ // detect ignored files.
+ ignoreFilterOnce sync.Once
+ ignoreFilter *ignoreFilter
}
var globalSnapshotID uint64
@@ -1195,7 +1200,7 @@
func moduleForURI(modFiles map[span.URI]struct{}, uri span.URI) span.URI {
var match span.URI
for modURI := range modFiles {
- if !source.InDir(span.Dir(modURI).Filename(), uri.Filename()) {
+ if !source.InDir(filepath.Dir(modURI.Filename()), uri.Filename()) {
continue
}
if len(modURI) > len(match) {