Commit ec0e2edd authored by Martin Möhrmann's avatar Martin Möhrmann

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: default avatarDaniel Martí <mvdan@mvdan.cc>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 4410900a
......@@ -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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment