Skip to content

x/tools/go/packages: bad performance #30677

Closed
@anjmao

Description

@anjmao

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.

Related issues:
#29758
#29452
#29427

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions