lookup_test.go raw

   1  // Copyright 2022 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  package types_test
   6  
   7  import (
   8  	"go/token"
   9  	"path/filepath"
  10  	"runtime"
  11  	"testing"
  12  
  13  	. "go/types"
  14  )
  15  
  16  // BenchmarkLookupFieldOrMethod measures types.LookupFieldOrMethod performance.
  17  // LookupFieldOrMethod is a performance hotspot for both type-checking and
  18  // external API calls.
  19  func BenchmarkLookupFieldOrMethod(b *testing.B) {
  20  	// Choose an arbitrary, large package.
  21  	path := filepath.Join(runtime.GOROOT(), "src", "net", "http")
  22  
  23  	fset := token.NewFileSet()
  24  	files, err := pkgFiles(fset, path)
  25  	if err != nil {
  26  		b.Fatal(err)
  27  	}
  28  
  29  	conf := Config{
  30  		Importer: defaultImporter(fset),
  31  	}
  32  
  33  	pkg, err := conf.Check("http", fset, files, nil)
  34  	if err != nil {
  35  		b.Fatal(err)
  36  	}
  37  
  38  	scope := pkg.Scope()
  39  	names := scope.Names()
  40  
  41  	// Look up an arbitrary name for each type referenced in the package scope.
  42  	lookup := func() {
  43  		for _, name := range names {
  44  			typ := scope.Lookup(name).Type()
  45  			LookupFieldOrMethod(typ, true, pkg, "m")
  46  		}
  47  	}
  48  
  49  	// Perform a lookup once, to ensure that any lazily-evaluated state is
  50  	// complete.
  51  	lookup()
  52  
  53  	b.ResetTimer()
  54  	for i := 0; i < b.N; i++ {
  55  		lookup()
  56  	}
  57  }
  58