]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: speed up ifaceeq for direct ifaces
authorJosh Bleecher Snyder <josharian@gmail.com>
Sun, 2 Dec 2018 18:15:35 +0000 (10:15 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 27 Feb 2019 18:07:25 +0000 (18:07 +0000)
name                    old time/op  new time/op  delta
EfaceCmpDiff-8           421ns ± 3%   299ns ± 3%  -28.93%  (p=0.000 n=92+94)
EfaceCmpDiffIndirect-8   497ns ± 4%   496ns ± 3%     ~     (p=0.840 n=98+92)

Change-Id: Id1a8c779413ba35ab0f58d055870b6a0714b51b7
Reviewed-on: https://go-review.googlesource.com/c/152163
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/runtime/alg.go
src/runtime/runtime_test.go

index 887dbebdeb074a5c4dfcc1b81e6ac427d2571300..1c6795a1faffde8ee20bbeed3b51f8f811547eb9 100644 (file)
@@ -224,7 +224,10 @@ func efaceeq(t *_type, x, y unsafe.Pointer) bool {
                panic(errorString("comparing uncomparable type " + t.string()))
        }
        if isDirectIface(t) {
-               return eq(noescape(unsafe.Pointer(&x)), noescape(unsafe.Pointer(&y)))
+               // Direct interface types are ptr, chan, map, func, and single-element structs/arrays thereof.
+               // Maps and funcs are not comparable, so they can't reach here.
+               // Ptrs, chans, and single-element items can be compared directly using ==.
+               return x == y
        }
        return eq(x, y)
 }
@@ -238,7 +241,8 @@ func ifaceeq(tab *itab, x, y unsafe.Pointer) bool {
                panic(errorString("comparing uncomparable type " + t.string()))
        }
        if isDirectIface(t) {
-               return eq(noescape(unsafe.Pointer(&x)), noescape(unsafe.Pointer(&y)))
+               // See comment in efaceeq.
+               return x == y
        }
        return eq(x, y)
 }
index 8263d4059a9e928d90317f7c656f8336b40f64e2..5ea9cbd88a125f01020f1a2950eac7c3ef40b666 100644 (file)
@@ -70,6 +70,18 @@ func BenchmarkEfaceCmpDiff(b *testing.B) {
        }
 }
 
+func BenchmarkEfaceCmpDiffIndirect(b *testing.B) {
+       efaceCmp1 = [2]int{1, 2}
+       efaceCmp2 = [2]int{1, 2}
+       for i := 0; i < b.N; i++ {
+               for j := 0; j < 100; j++ {
+                       if efaceCmp1 != efaceCmp2 {
+                               b.Fatal("bad comparison")
+                       }
+               }
+       }
+}
+
 func BenchmarkDefer(b *testing.B) {
        for i := 0; i < b.N; i++ {
                defer1()