1
0
mirror of https://github.com/golang/go synced 2024-11-19 16:14:49 -07:00

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 <moehrmann@google.com>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Martin Möhrmann 2017-09-06 08:36:10 +02:00
parent 4410900a3c
commit ec0e2edd3b

View File

@ -373,15 +373,14 @@ again:
growWork_fast32(t, h, bucket) growWork_fast32(t, h, bucket)
} }
b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize))) b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
top := tophash(hash)
var inserti *uint8 var inserti *uint8
var insertk unsafe.Pointer var insertk unsafe.Pointer
var val unsafe.Pointer var val unsafe.Pointer
for { for {
for i := uintptr(0); i < bucketCnt; i++ { for i := uintptr(0); i < bucketCnt; i++ {
if b.tophash[i] != top { if b.tophash[i] == empty {
if b.tophash[i] == empty && inserti == nil { if inserti == nil {
inserti = &b.tophash[i] inserti = &b.tophash[i]
insertk = add(unsafe.Pointer(b), dataOffset+i*4) insertk = add(unsafe.Pointer(b), dataOffset+i*4)
val = add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize)) val = add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize))
@ -425,7 +424,8 @@ again:
} else { } else {
*(*uint32)(insertk) = key *(*uint32)(insertk) = key
} }
*inserti = top
*inserti = tophash(hash)
h.count++ h.count++
done: done:
@ -462,15 +462,14 @@ again:
growWork_fast64(t, h, bucket) growWork_fast64(t, h, bucket)
} }
b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize))) b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
top := tophash(hash)
var inserti *uint8 var inserti *uint8
var insertk unsafe.Pointer var insertk unsafe.Pointer
var val unsafe.Pointer var val unsafe.Pointer
for { for {
for i := uintptr(0); i < bucketCnt; i++ { for i := uintptr(0); i < bucketCnt; i++ {
if b.tophash[i] != top { if b.tophash[i] == empty {
if b.tophash[i] == empty && inserti == nil { if inserti == nil {
inserti = &b.tophash[i] inserti = &b.tophash[i]
insertk = add(unsafe.Pointer(b), dataOffset+i*8) insertk = add(unsafe.Pointer(b), dataOffset+i*8)
val = add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize)) val = add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize))
@ -521,7 +520,7 @@ again:
*(*uint64)(insertk) = key *(*uint64)(insertk) = key
} }
*inserti = top *inserti = tophash(hash)
h.count++ h.count++
done: done: