]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: optimize directlyAssignable to avoid rtype.Name call
authorSergei Zagurskii <gvozdoder@gmail.com>
Wed, 22 May 2019 14:00:34 +0000 (17:00 +0300)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 27 Aug 2019 16:44:22 +0000 (16:44 +0000)
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>
src/internal/reflectlite/type.go
src/reflect/type.go

index 03274bcd4c82d0c5f7f7e788fd6d3aaad937772d..c706319a8e24adb8f2086ecf54b2a35fae7a25ed 100644 (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
        }
 
index 7aafc505bd91bdca98315eec59c06f19d3eef23b..4afe634bbf9be44c92cadbb6c74a664117a886d5 100644 (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
        }