1
0
mirror of https://github.com/golang/go synced 2024-09-29 11:34:32 -06:00

reflect: optimize directlyAssignable to avoid rtype.Name call

directlyAssignable invoked rtype.Name() just to compare its result
to empty string. We really only need to check whether rtype has
name. It can be done much cheaper, by checking tflagNamed.

Benchmark: https://play.golang.org/p/V2BzESPuf2w
name                   old time/op  new time/op  delta
DirectlyAssignable-12  32.7ns ± 6%   6.6ns ± 6%  -79.80%  (p=0.008 n=5+5)

Fixes #32186

Change-Id: I1a2a167dbfddf319fba3015cb6a011bf010f99a8
Reviewed-on: https://go-review.googlesource.com/c/go/+/178518
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Sergei Zagurskii 2019-05-22 17:00:34 +03:00 committed by Brad Fitzpatrick
parent dca0d03b9c
commit 8057c0887f
2 changed files with 12 additions and 4 deletions

View File

@ -521,8 +521,12 @@ func (t *rtype) PkgPath() string {
return t.nameOff(ut.pkgPath).name()
}
func (t *rtype) hasName() bool {
return t.tflag&tflagNamed != 0
}
func (t *rtype) Name() string {
if t.tflag&tflagNamed == 0 {
if !t.hasName() {
return ""
}
s := t.String()
@ -782,7 +786,7 @@ func directlyAssignable(T, V *rtype) bool {
// Otherwise at least one of T and V must not be defined
// and they must have the same kind.
if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() {
if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
return false
}

View File

@ -871,8 +871,12 @@ func hasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
func (t *rtype) hasName() bool {
return t.tflag&tflagNamed != 0
}
func (t *rtype) Name() string {
if t.tflag&tflagNamed == 0 {
if !t.hasName() {
return ""
}
s := t.String()
@ -1563,7 +1567,7 @@ func directlyAssignable(T, V *rtype) bool {
// Otherwise at least one of T and V must not be defined
// and they must have the same kind.
if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() {
if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
return false
}