Skip to content

x/tools/gopls: The completion feature of gopls has high latency when dealing with very large packages. #69631

@pand5a

Description

@pand5a

gopls version

golang.org/x/tools/gopls v0.16.2

go env

GO111MODULE='auto'
GOARCH='amd64'
GOBIN=''
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH=''
GOPRIVATE=''
GOROOT='/usr/lib/go'
GOSUMDB='off'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.23.1'
GODEBUG=''
GOTELEMETRY='local'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1211819663=/tmp/go-build -gno-record-gcc-switches'

What did you do?

The completion feature of gopls has high latency when dealing with very large packages. Below are the completion latencies observed in the sql package of the cockroachdb source code.

The code statistics for the sql package in cockroachdb are as follows:

cloc cockroach/pkg/sql             
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Go                            2974         148944         228093        1355540
-------------------------------------------------------------------------------
SUM:                          3504         152684         236151        1424410
-------------------------------------------------------------------------------

The distribution of the main function latencies in gopls completion is as follows:

completion.go:54: elapsed 489.202836ms,        Completion entry, 
completion.go:484: elapsed 477.769576ms,            NarrowestPackageForFile, 
snapshot.go:87: elapsed 477.709921ms,                   TypeCheck, 
check.go:415: elapsed 37.059356ms,                          getPackageHandles,
check.go:422: elapsed  51.8002ms,                           getImportGraph, 
check.go:606: elapsed   194.72µs,                           getImportPackage
check.go:629: elapsed 387.29934ms,                          checkPackage, 
check.go:1614: elapsed 385.05347ms,                             check.Files

The most time-consuming part is ** check.go:1614: elapsed 385.05347ms, check.Files, 288 **, which takes around 385 milliseconds. Adding other operations, the total latency reaches 489.202836ms. This results in noticeable lag during use.

What did you see happen?

During each completion, a TypeCheck is performed on the package containing the currently modified file, and this process is very time-consuming for large packages.

What did you expect to see?

Is it possible to only re-parse the current file during completion, rather than performing a TypeCheck on the entire package? This would allow completion to be completed in milliseconds even for large packages.

Editor and settings

nvim

Logs

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    ToolsThis label describes issues relating to any tools in the x/tools repository.goplsIssues related to the Go language server, gopls.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions