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

runtime: strength reduce key pointer calculation in mapdelete_fast*

Move the tophash checks after the equality/length checks.

For fast32/fast64, since we've done a full equality check already,
just check whether tophash is empty instead of checking tophash.
This is cheaper and allows us to skip calculating tophash.

These changes are modeled on the changes in CL 57590,
which were polished based on benchmarking.
Benchmarking directly is impeded by #21546.

Change-Id: I0e17163028e34720310d1bf8f95c5ef42d223e00
Reviewed-on: https://go-review.googlesource.com/57611
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2017-08-21 09:54:36 -07:00
parent 61043d4671
commit 29e6bdc69c

View File

@ -647,14 +647,9 @@ func mapdelete_fast32(t *maptype, h *hmap, key uint32) {
growWork(t, h, bucket)
}
b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
top := tophash(hash)
for {
for i := uintptr(0); i < bucketCnt; i++ {
if b.tophash[i] != top {
continue
}
k := (*uint32)(add(unsafe.Pointer(b), dataOffset+i*4))
if key != *k {
for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 4) {
if key != *(*uint32)(k) || b.tophash[i] == empty {
continue
}
typedmemclr(t.key, unsafe.Pointer(k))
@ -699,14 +694,9 @@ func mapdelete_fast64(t *maptype, h *hmap, key uint64) {
growWork(t, h, bucket)
}
b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
top := tophash(hash)
for {
for i := uintptr(0); i < bucketCnt; i++ {
if b.tophash[i] != top {
continue
}
k := (*uint64)(add(unsafe.Pointer(b), dataOffset+i*8))
if key != *k {
for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
if key != *(*uint64)(k) || b.tophash[i] == empty {
continue
}
typedmemclr(t.key, unsafe.Pointer(k))
@ -754,12 +744,9 @@ func mapdelete_faststr(t *maptype, h *hmap, ky string) {
b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
top := tophash(hash)
for {
for i := uintptr(0); i < bucketCnt; i++ {
if b.tophash[i] != top {
continue
}
k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*sys.PtrSize))
if k.len != key.len {
for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*sys.PtrSize) {
k := (*stringStruct)(kptr)
if k.len != key.len || b.tophash[i] != top {
continue
}
if k.str != key.str && !memequal(k.str, key.str, uintptr(key.len)) {