From: Josh Bleecher Snyder Date: Sun, 2 Dec 2018 18:15:35 +0000 (-0800) Subject: runtime: speed up ifaceeq for direct ifaces X-Git-Tag: go1.13beta1~1329 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=694cd005c3943027a4533a0a534837108ccd66f6;p=gostls13.git runtime: speed up ifaceeq for direct ifaces 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 TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- diff --git a/src/runtime/alg.go b/src/runtime/alg.go index 887dbebdeb..1c6795a1fa 100644 --- a/src/runtime/alg.go +++ b/src/runtime/alg.go @@ -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) } diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go index 8263d4059a..5ea9cbd88a 100644 --- a/src/runtime/runtime_test.go +++ b/src/runtime/runtime_test.go @@ -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()