Seems simple, but putting the return after fatal ensures that at the
point of the small group loop, no call has happened so the key is
still in a register. This ensures that we don't have to restore the
key from the stack before the comparison on each iteration. That gets
rid of a load from the inner loop.
name old time/op new time/op delta
MapAccessHit/Key=int64/Elem=int64/len=6-8 4.01ns ± 6% 3.85ns ± 3% -3.92% (p=0.001 n=10+10)
Change-Id: Ia23ac48e6c5522be88f7d9be0ff3489b2dfc52fc
Reviewed-on: https://go-review.googlesource.com/c/go/+/624255
Reviewed-by: 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>
match = g.ctrls().matchEmptyOrDeleted()
if match == 0 {
fatal("small map with no empty slot (concurrent map writes?)")
+ return nil
}
i := match.first()
if m.writing != 0 {
fatal("concurrent map read and map write")
+ return nil
}
if m.dirLen == 0 {
if m.writing != 0 {
fatal("concurrent map read and map write")
+ return nil, false
}
if m.dirLen == 0 {
if m.writing != 0 {
fatal("concurrent map read and map write")
+ return nil
}
if m.dirLen == 0 {
if m.writing != 0 {
fatal("concurrent map read and map write")
+ return nil, false
}
if m.dirLen == 0 {
if m.writing != 0 {
fatal("concurrent map read and map write")
+ return nil
}
hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
if m.writing != 0 {
fatal("concurrent map read and map write")
+ return nil, false
}
hash := typ.Hasher(abi.NoEscape(unsafe.Pointer(&key)), m.seed)
if it.m.writing != 0 {
fatal("concurrent map iteration and map write")
+ return
}
if it.dirIdx < 0 {