]> Cypherpunks repositories - gostls13.git/commitdiff
internal/runtime/maps: don't hash twice when deleting
authorKeith Randall <khr@golang.org>
Sat, 9 Nov 2024 17:53:09 +0000 (09:53 -0800)
committerKeith Randall <khr@golang.org>
Mon, 11 Nov 2024 23:50:34 +0000 (23:50 +0000)
                     │  baseline   │             experiment              │
                     │   sec/op    │   sec/op     vs base                │
MapDeleteLargeKey-24   312.0n ± 6%   162.3n ± 5%  -47.97% (p=0.000 n=10)

Change-Id: I31f1f8e3c344cf8abf2e9eb4b51b78fcd67b93c4
Reviewed-on: https://go-review.googlesource.com/c/go/+/625906
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>
src/internal/runtime/maps/map.go
src/internal/runtime/maps/table.go
src/runtime/map_benchmark_test.go

index 9ebc72a524feb23c877e0334a04fa97559662b32..86977bbc2d50870b530b76b37553c24f1d7ca6ad 100644 (file)
@@ -663,7 +663,7 @@ func (m *Map) Delete(typ *abi.SwissMapType, key unsafe.Pointer) {
                m.deleteSmall(typ, hash, key)
        } else {
                idx := m.directoryIndex(hash)
-               m.directoryAt(idx).Delete(typ, m, key)
+               m.directoryAt(idx).Delete(typ, m, hash, key)
        }
 
        if m.used == 0 {
index 55c9879c3f04e457288870c8b0f02309fffaccd6..eae23d84c9735f016b60c27192153b70e5c95123 100644 (file)
@@ -409,9 +409,7 @@ func (t *table) uncheckedPutSlot(typ *abi.SwissMapType, hash uintptr, key unsafe
        }
 }
 
-func (t *table) Delete(typ *abi.SwissMapType, m *Map, key unsafe.Pointer) {
-       hash := typ.Hasher(key, m.seed)
-
+func (t *table) Delete(typ *abi.SwissMapType, m *Map, hash uintptr, key unsafe.Pointer) {
        seq := makeProbeSeq(h1(hash), t.groups.lengthMask)
        for ; ; seq = seq.next() {
                g := t.groups.group(typ, seq.offset)
index 3b83de59cdfd35ff550823474aabd2274e654fdb..5f0304264907f9fced9802d58fae1cdd41899c1d 100644 (file)
@@ -1090,3 +1090,14 @@ func BenchmarkMapPop(b *testing.B) {
        b.Run("Key=*int32/Elem=int32", benchSizes(benchmarkMapPop[*int32, int32]))
        b.Run("Key=int32/Elem=*int32", benchSizes(benchmarkMapPop[int32, *int32]))
 }
+
+func BenchmarkMapDeleteLargeKey(b *testing.B) {
+       m := map[string]int{}
+       for i := range 9 {
+               m[fmt.Sprintf("%d", i)] = i
+       }
+       key := strings.Repeat("*", 10000)
+       for range b.N {
+               delete(m, key)
+       }
+}