go: x/tools/gopls: imports extremely slow with large module cache
What version of Go are you using (go version)?
$ go version go version devel +44c9354c5a Fri Jun 21 05:21:30 2019 +0000 linux/amd64 $ go list -m golang.org/x/tools golang.org/x/tools v0.0.0-20190620191750-1fa568393b23 $ go list -m golang.org/x/tools/gopls golang.org/x/tools/gopls v0.0.0-20190620191750-1fa568393b23
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="on" GOARCH="amd64" GOBIN="/home/myitcv/gostuff/src/github.com/myitcv/govim/cmd/govim/.bin" GOCACHE="/home/myitcv/.cache/go-build" GOENV="/home/myitcv/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/myitcv/gostuff" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/home/myitcv/gos" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/home/myitcv/gos/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/home/myitcv/gostuff/src/github.com/myitcv/govim/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build977371100=/tmp/go-build -gno-record-gcc-switches"
What did you do?
The issue I keep tripping across is making refactoring changes that, for example, rename variables. If I fail to rename all instances of the variable (perhaps I’ve copy-pasted some code from somewhere), there’s a chance I’ve left behind a selector expression with the old variable name… which is now treated by imports as if it were a qualified identifier for a package that has not yet been imported.
Like https://github.com/golang/go/issues/32726, imports then heads off into the module cache searching through all potential matches. With a 5GB module cache, this is not a quick operation.
I think imports should:
- pre-load and cache its results from the module cache
- have that cache be invalidated where the modification time of any non-module cache-based
go.{mod,sum}reachable from the main module changes - when the cache is invalidated, re-warm the cache in the background
Yes, this will cause possibly stale results in the case that another main module causes changes in the module cache, but I think that’s a sacrifice worth making for the general speed of imports.
What did you expect to see?
Instant responses to imports-based format-on-save.
What did you see instead?
~10sec delays.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 14
- Comments: 34 (20 by maintainers)
Can you sync to master (
go get -u golang.org/x/tools/gopls@master)? I just submitted a fix for this nil pointer.Thanks. See some benefits here as a result of https://golang.org/cl/184921 and https://golang.org/cl/186301.
This will also help. However, for Vim users (via whatever plugin) this will also likely become something of a pain. Because Vim users typically start/stop Vim regularly, especially when used from the terminal. Hence, if
goplsis being started/stopped each time (communicating over stdin/stdout) then every time Vim is started (and there are often multiple instances of Vim open) this pre-warming will happen.So any pre-warming will, I suspect, need to go hand-in-hand with ensuring the socket-based communication with
goplsis on a par with the pipe-based approach. I would guess it is, but cc @stamblerre and @ianthehat for thoughts?We have started reusing the imports resolver in gopls (https://golang.org/cl/184921) and added some caching of packages in the module cache (https://golang.org/cl/186301), which both work to speed up imports when there have been no go.mod file changes.
A new caching design is currently being implemented to avoid repeat work of scanning the module cache.
Pre-warming of this cache has not been implemented yet.
Chiming in here to say I’ve been staying reasonably current on
goplsand things seem to be working much better for me now. I can’t pinpoint the exact time things got better, but I haven’t had a case of getting stuck importing and needing to resolve by hand for at least a week.