From 29e6bdc69c580cf6e9c4cc27600b7f4e2b0def9f Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Mon, 21 Aug 2017 09:54:36 -0700 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/runtime/hashmap_fast.go | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/src/runtime/hashmap_fast.go b/src/runtime/hashmap_fast.go index 1d830cc8cf..2fda9f4255 100644 --- a/src/runtime/hashmap_fast.go +++ b/src/runtime/hashmap_fast.go @@ -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)) {