From 808da68c1c66e05a04a7d4bc046f27811711d7ff Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Mon, 19 Aug 2024 17:45:41 -0400 Subject: [PATCH] internal/runtime/maps: linear scan of small map 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 Auto-Submit: Michael Pratt LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall --- src/internal/runtime/maps/map.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/internal/runtime/maps/map.go b/src/internal/runtime/maps/map.go index 112fc08e0f..ad6edd65bf 100644 --- a/src/internal/runtime/maps/map.go +++ b/src/internal/runtime/maps/map.go @@ -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