]> Cypherpunks repositories - gostls13.git/commitdiff
internal/runtime/maps: linear scan of small map
authorMichael Pratt <mpratt@google.com>
Mon, 19 Aug 2024 21:45:41 +0000 (17:45 -0400)
committerGopher Robot <gobot@golang.org>
Mon, 28 Oct 2024 20:35:27 +0000 (20:35 +0000)
We still use the hash and control word, but loop over all 8 bytes
instead of doing the match operation, which ends up being slightly
faster when there is only one group.

Note that specialized variants added later will avoid hashing at all.

For #54766.

Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest-swissmap
Change-Id: I3bb353b023dd6120b6585e87d3efe2f18ac9e1ef
Reviewed-on: https://go-review.googlesource.com/c/go/+/611189
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
src/internal/runtime/maps/map.go

index 112fc08e0fe22fb01ce36bf5c785cb1dedc962c2..ad6edd65bf4a4e09dc6090cde9050f1fdc7e1c88 100644 (file)
@@ -381,16 +381,20 @@ func (m *Map) getWithKeySmall(hash uintptr, key unsafe.Pointer) (unsafe.Pointer,
                data: m.dirPtr,
        }
 
-       match := g.ctrls().matchH2(h2(hash))
+       h2 := uint8(h2(hash))
+       ctrls := *g.ctrls()
 
-       for match != 0 {
-               i := match.first()
+       for i := uint32(0); i < abi.SwissMapGroupSlots; i++ {
+               c := uint8(ctrls)
+               ctrls >>= 8
+               if c != h2 {
+                       continue
+               }
 
                slotKey := g.key(i)
                if m.typ.Key.Equal(key, slotKey) {
                        return slotKey, g.elem(i), true
                }
-               match = match.removeFirst()
        }
 
        return nil, nil, false