golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.06k stars 17.68k forks source link

x/tools/gopls: saving is very slow with the latest update #45092

Closed evanw closed 3 years ago

evanw commented 3 years ago

What version of Go are you using (go version)?

$ go version
go version go1.16.2 darwin/amd64

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=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/evan/Library/Caches/go-build"
GOENV="/Users/evan/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/evan/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/evan/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16.2"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/evan/dev/esbuild/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 -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/j6/np400cw17sz0n5ljd67byrzw0000gn/T/go-build1589752302=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I use the Go extension in Visual Studio Code (v0.23.2) which uses gopls (v0.6.7) on a project with a single dependency.

What did you expect to see?

The Go extension formats code and automatically inserts missing imports whenever I save. I expect this to feel instant, and it has been instant in the past.

What did you see instead?

Something changed recently. Now saving a Go file takes a really long time (e.g. 7 seconds) and causes Visual Studio Code to show a Saving 'resolver.go': Getting code actions from ''Go'' (configure). message in the corner. This is really breaking my flow because it means I constantly have to wait in between adjusting code and trying it out.

I would love for this to be fixed of course, but I would also love to have a workaround in the meantime. For example, I assume this is due to automatic import insertion and not due to code formatting. Is there a way I can disable the slow part but just keep code formatting on save? Maybe there is some cache somewhere that has gotten filled up and can be cleared to make this go faster?

stamblerre commented 3 years ago

Can you please share your gopls logs? Information on how to capture them can be found here.

evanw commented 3 years ago

Here's a log capture: gopls-slow-save.log. This is the result of clearing the log, changing the indentation of a single line, re-saving the file, and waiting for the file to be saved. This particular save operation took around around 23 seconds to complete.

I do have a lot of files under the top-level project directory in case that's what's causing this. The count from find . | wc -l in the top-level project directory is 351,777 files and directories. This is because I'm writing a JavaScript bundler and there are some projects I use for testing with node_modules directories. These test projects are all under .gitignore however.

Edit: And the Go-specific lines of my Visual Studio Code settings.json file are these:

    "go.lintOnSave": "off",
    "go.vetOnSave": "off",
    "go.formatTool": "goimports",
    "go.languageServerFlags": [
        "-rpc.trace"
    ],
    "[go]": {
        "editor.insertSpaces": false,
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.organizeImports": true
        }
    },
SimonRichardson commented 3 years ago

Also experiencing the same issue with a large codebase[1]

  1. https://github.com/juju/juju

I'm currently attempting to downgrade gopls to identify when the slowdown was introduced.

gopherbot commented 3 years ago

Change https://golang.org/cl/303149 mentions this issue: internal/lsp: remove module diagnostics from code actions

gopherbot commented 3 years ago

Change https://golang.org/cl/303150 mentions this issue: internal/lsp: remove module diagnostics from code actions

stamblerre commented 3 years ago

Thank you for these reports. We were able to debug this issue using the juju repository, and we'll have a patch release out to fix this soon. You can try it out now by downloading gopls at master: GO111MODULE=on go get golang.org/x/tools/gopls@master golang.org/x/tools@master. Please let us know if the issue is resolved at master.

evanw commented 3 years ago

I just updated and it appears to be fixed! Thanks so much for the fix.

gopherbot commented 3 years ago

Change https://golang.org/cl/356255 mentions this issue: doc: document new reflect.UnsafePointer function