Closed
Description
Problem
There is quite a lot of issues regarding go/packages performance. All tools which a migrating to go modules a going to use x/tools/go/packages which is undesirable slow.
go version go1.11.2 darwin/amd64
Steps to reproduce
parse_me.go
package dotest
import (
"fmt"
"time"
)
func bar() {
fmt.Println(time.Now())
}
benchmark_test.go
package main
import (
"fmt"
"go/parser"
"go/token"
"log"
"os"
"testing"
"golang.org/x/tools/go/packages"
)
const (
rootPath = "<path_to_folder>"
filePath = "<path_to_folder>/parse_me.go"
)
func BenchmarkParseWithStd(b *testing.B) {
for i := 0; i < b.N; i++ {
parseWithStd()
}
}
func BenchmarkLoadAllSyntax(b *testing.B) { benchmarkLoadPkg(b, packages.LoadAllSyntax) }
func BenchmarkLoadSyntax(b *testing.B) { benchmarkLoadPkg(b, packages.LoadSyntax) }
func BenchmarkLoadTypes(b *testing.B) { benchmarkLoadPkg(b, packages.LoadTypes) }
func BenchmarkLoadImports(b *testing.B) { benchmarkLoadPkg(b, packages.LoadImports) }
func benchmarkLoadPkg(b *testing.B, loadMode packages.LoadMode) {
for i := 0; i < b.N; i++ {
parseWithModules(loadMode)
}
}
func parseWithStd() {
fset := token.NewFileSet()
_, err := parser.ParseFile(fset, filePath, nil, parser.AllErrors|parser.ParseComments)
if err != nil {
log.Fatal(err)
}
}
func parseWithModules(loadMode packages.LoadMode) {
fset := token.NewFileSet()
cfg := &packages.Config{
Dir: rootPath,
Mode: loadMode,
Fset: fset,
Overlay: make(map[string][]byte),
Tests: true,
}
pkgs, err := packages.Load(cfg, fmt.Sprintf("file=%s", filePath))
if err != nil {
log.Fatal(err)
}
if packages.PrintErrors(pkgs) > 0 {
os.Exit(1)
}
}
Results
BenchmarkParseWithStd-8 50000 33231 ns/op 3632 B/op 68 allocs/op
BenchmarkLoadAllSyntax-8 2 717116925 ns/op 138813840 B/op 1329883 allocs/op
BenchmarkLoadSyntax-8 10 132804220 ns/op 2685484 B/op 5810 allocs/op
BenchmarkLoadTypes-8 10 131061186 ns/op 435418 B/op 3812 allocs/op
BenchmarkLoadImports-8 10 112006365 ns/op 390102 B/op 3423 allocs/op
Is somebody working on it? If not I'm happy to help.