]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: avoid extra tophash check in mapassign when key comparison is cheap
authorMartin Möhrmann <moehrmann@google.com>
Wed, 6 Sep 2017 06:36:10 +0000 (08:36 +0200)
committerMartin Möhrmann <moehrmann@google.com>
Thu, 7 Sep 2017 06:34:12 +0000 (06:34 +0000)
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>

src/runtime/hashmap_fast.go

index 21e1f68bf778df85247a4a540243deef33e913ee..e7b84482032032bb628d74c42ce72356bce4ac06 100644 (file)
@@ -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: