]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: strength reduce key pointer calculation in mapdelete_fast*
authorJosh Bleecher Snyder <josharian@gmail.com>
Mon, 21 Aug 2017 16:54:36 +0000 (09:54 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 23 Aug 2017 13:49:52 +0000 (13:49 +0000)
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>
src/runtime/hashmap_fast.go

index 1d830cc8cfeb3471fe3bdb645f2bac793cd48786..2fda9f425550d2308a928dd105ecf2376bac374a 100644 (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)) {