From 8057c0887f89701b3091755d986b534fd8a50fc7 Mon Sep 17 00:00:00 2001 From: Sergei Zagurskii Date: Wed, 22 May 2019 17:00:34 +0300 Subject: [PATCH] reflect: optimize directlyAssignable to avoid rtype.Name call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/internal/reflectlite/type.go | 8 ++++++-- src/reflect/type.go | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/internal/reflectlite/type.go b/src/internal/reflectlite/type.go index 03274bcd4c..c706319a8e 100644 --- a/src/internal/reflectlite/type.go +++ b/src/internal/reflectlite/type.go @@ -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 } diff --git a/src/reflect/type.go b/src/reflect/type.go index 7aafc505bd..4afe634bbf 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -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 }