From: Martin Möhrmann Date: Wed, 6 Sep 2017 06:36:10 +0000 (+0200) Subject: runtime: avoid extra tophash check in mapassign when key comparison is cheap X-Git-Tag: go1.10beta1~1202 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ec0e2edd3b8e92ca003416a4cdbd9b7345d9d38f;p=gostls13.git runtime: avoid extra tophash check in mapassign when key comparison is cheap mapaccess and mapdelete functions are already optimized to prefer direct key comparison instead of tophash checks when key comparison is cheap. Extended version of golang.org/cl/55235. AMD64: name old time/op new time/op delta MapPopulate/1 42.5ns ± 2% 40.3ns ± 2% -5.37% (p=0.000 n=9+10) MapPopulate/10 558ns ± 1% 556ns ± 1% ~ (p=0.157 n=10+10) MapPopulate/100 7.75µs ± 1% 7.66µs ± 2% -1.19% (p=0.001 n=10+10) MapPopulate/1000 92.6µs ± 1% 92.0µs ± 1% -0.61% (p=0.016 n=10+8) MapPopulate/10000 817µs ± 1% 814µs ± 1% ~ (p=0.247 n=10+10) MapPopulate/100000 8.02ms ± 1% 7.90ms ± 2% -1.47% (p=0.007 n=10+10) Change-Id: If0eca9931379cbbd37eb753e9bcd2888d8272153 Reviewed-on: https://go-review.googlesource.com/62050 Run-TryBot: Martin Möhrmann Reviewed-by: Daniel Martí Reviewed-by: Keith Randall TryBot-Result: Gobot Gobot --- diff --git a/src/runtime/hashmap_fast.go b/src/runtime/hashmap_fast.go index 21e1f68bf7..e7b8448203 100644 --- a/src/runtime/hashmap_fast.go +++ b/src/runtime/hashmap_fast.go @@ -373,15 +373,14 @@ again: growWork_fast32(t, h, bucket) } b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize))) - top := tophash(hash) var inserti *uint8 var insertk unsafe.Pointer var val unsafe.Pointer for { for i := uintptr(0); i < bucketCnt; i++ { - if b.tophash[i] != top { - if b.tophash[i] == empty && inserti == nil { + if b.tophash[i] == empty { + if inserti == nil { inserti = &b.tophash[i] insertk = add(unsafe.Pointer(b), dataOffset+i*4) val = add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize)) @@ -425,7 +424,8 @@ again: } else { *(*uint32)(insertk) = key } - *inserti = top + + *inserti = tophash(hash) h.count++ done: @@ -462,15 +462,14 @@ again: growWork_fast64(t, h, bucket) } b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize))) - top := tophash(hash) var inserti *uint8 var insertk unsafe.Pointer var val unsafe.Pointer for { for i := uintptr(0); i < bucketCnt; i++ { - if b.tophash[i] != top { - if b.tophash[i] == empty && inserti == nil { + if b.tophash[i] == empty { + if inserti == nil { inserti = &b.tophash[i] insertk = add(unsafe.Pointer(b), dataOffset+i*8) val = add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize)) @@ -521,7 +520,7 @@ again: *(*uint64)(insertk) = key } - *inserti = top + *inserti = tophash(hash) h.count++ done: