detect which objects are global in a simpler way

To detect if an object is global, our previous code did:

	obj.Pkg().Scope().Lookup(obj.Name()) == obj

However, that Lookup call is unnecessary.
It is a map lookup, which is cheap, but not free.
Instead, we can compare the scopes directly:

	obj.Pkg().Scope() == obj.Parent()

While here, reuse the calls to obj.Pkg(),
and avoid using fmt.Sprintf in this hot path.

Looked here since perf on Linux with a garble build
reports that we spend about 2.6% of CPU time in recordedObjectString.
Overall provides a very minor improvement:

	name      old time/op         new time/op         delta
	Build-16          21.8s ± 1%          21.7s ± 0%    ~     (p=0.200 n=4+4)

	name      old bin-B           new bin-B           delta
	Build-16          5.67M ± 0%          5.67M ± 0%    ~     (all equal)

	name      old cached-time/op  new cached-time/op  delta
	Build-16          734ms ± 3%          722ms ± 3%    ~     (p=0.486 n=4+4)

	name      old mallocs/op      new mallocs/op      delta
	Build-16          25.0M ± 0%          24.7M ± 0%  -1.28%  (p=0.029 n=4+4)

	name      old sys-time/op     new sys-time/op     delta
	Build-16          17.0s ± 1%          16.8s ± 1%    ~     (p=0.200 n=4+4)
pull/643/head
Daniel Martí 1 year ago committed by lu4p
parent 8ea0708bca
commit 7e95fcf1cb

@ -1607,6 +1607,7 @@ func (tf *transformer) recordType(used, origin types.Type) {
// if that shows an improvement in our benchmark
func recordedObjectString(obj types.Object) objectString {
pkg := obj.Pkg()
if obj, ok := obj.(*types.Var); ok && obj.IsField() {
// For exported fields, "pkgpath.Field" is not unique,
// because two exported top-level types could share "Field".
@ -1623,17 +1624,17 @@ func recordedObjectString(obj types.Object) objectString {
// numbers, but not column numbers nor byte offsets.
// TODO(mvdan): give this another think, and add tests involving anon types.
pos := fset.Position(obj.Pos())
return fmt.Sprintf("%s.%s - %s:%d", obj.Pkg().Path(), obj.Name(),
return fmt.Sprintf("%s.%s - %s:%d", pkg.Path(), obj.Name(),
filepath.Base(pos.Filename), pos.Line)
}
// Names which are not at the top level cannot be imported,
// so we don't need to record them either.
// Note that this doesn't apply to fields, which are never top-level.
if obj.Pkg().Scope().Lookup(obj.Name()) != obj {
if pkg.Scope() != obj.Parent() {
return ""
}
// For top-level exported names, "pkgpath.Name" is unique.
return fmt.Sprintf("%s.%s", obj.Pkg().Path(), obj.Name())
return pkg.Path() + "." + obj.Name()
}
// recordAsNotObfuscated records all the objects whose names we cannot obfuscate.

Loading…
Cancel
Save