From 8a85a2e70a97773ac96e899df7411eda4f5da2cb Mon Sep 17 00:00:00 2001 From: Mateusz Poliwczak Date: Mon, 7 Apr 2025 15:21:16 +0200 Subject: runtime, internal/runtime/maps: speed-up empty/zero map lookups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This lets the inliner do a better job optimizing the mapKeyError call. goos: linux goarch: amd64 pkg: runtime cpu: AMD Ryzen 5 4600G with Radeon Graphics │ /tmp/before2 │ /tmp/after3 │ │ sec/op │ sec/op vs base │ MapAccessZero/Key=int64-12 1.875n ± 0% 1.875n ± 0% ~ (p=0.506 n=25) MapAccessZero/Key=int32-12 1.875n ± 0% 1.875n ± 0% ~ (p=0.082 n=25) MapAccessZero/Key=string-12 1.902n ± 1% 1.902n ± 1% ~ (p=0.256 n=25) MapAccessZero/Key=mediumType-12 2.816n ± 0% 1.958n ± 0% -30.47% (p=0.000 n=25) MapAccessZero/Key=bigType-12 2.815n ± 0% 1.935n ± 0% -31.26% (p=0.000 n=25) MapAccessEmpty/Key=int64-12 1.942n ± 0% 2.109n ± 0% +8.60% (p=0.000 n=25) MapAccessEmpty/Key=int32-12 2.110n ± 0% 1.940n ± 0% -8.06% (p=0.000 n=25) MapAccessEmpty/Key=string-12 2.024n ± 0% 2.109n ± 0% +4.20% (p=0.000 n=25) MapAccessEmpty/Key=mediumType-12 3.157n ± 0% 2.344n ± 0% -25.75% (p=0.000 n=25) MapAccessEmpty/Key=bigType-12 3.054n ± 0% 2.115n ± 0% -30.75% (p=0.000 n=25) geomean 2.305n 2.011n -12.75% Change-Id: Iee83930884dc4c8a791a711aa189a1c93b68d536 Reviewed-on: https://go-review.googlesource.com/c/go/+/663495 Reviewed-by: Dmitri Shuralyov LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Pratt --- src/runtime/map_benchmark_test.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src/runtime/map_benchmark_test.go') diff --git a/src/runtime/map_benchmark_test.go b/src/runtime/map_benchmark_test.go index bf195fa30d..a26b35b44d 100644 --- a/src/runtime/map_benchmark_test.go +++ b/src/runtime/map_benchmark_test.go @@ -1191,3 +1191,39 @@ func BenchmarkMapSmallAccessMiss(b *testing.B) { b.Run("Key=string/Elem=string", smallBenchSizes(benchmarkMapAccessMiss[string, string])) b.Run("Key=smallType/Elem=int32", smallBenchSizes(benchmarkMapAccessMiss[smallType, int32])) } + +func mapAccessZeroBenchmark[K comparable](b *testing.B) { + var m map[K]uint64 + var key K + for i := 0; i < b.N; i++ { + sink = m[key] + } +} + +func BenchmarkMapAccessZero(b *testing.B) { + b.Run("Key=int64", mapAccessZeroBenchmark[int64]) + b.Run("Key=int32", mapAccessZeroBenchmark[int32]) + b.Run("Key=string", mapAccessZeroBenchmark[string]) + b.Run("Key=mediumType", mapAccessZeroBenchmark[mediumType]) + b.Run("Key=bigType", mapAccessZeroBenchmark[bigType]) +} + +func mapAccessEmptyBenchmark[K mapBenchmarkKeyType](b *testing.B) { + m := make(map[K]uint64) + for i, v := range genValues[K](0, 1000) { + m[v] = uint64(i) + } + clear(m) + var key K + for i := 0; i < b.N; i++ { + sink = m[key] + } +} + +func BenchmarkMapAccessEmpty(b *testing.B) { + b.Run("Key=int64", mapAccessEmptyBenchmark[int64]) + b.Run("Key=int32", mapAccessEmptyBenchmark[int32]) + b.Run("Key=string", mapAccessEmptyBenchmark[string]) + b.Run("Key=mediumType", mapAccessEmptyBenchmark[mediumType]) + b.Run("Key=bigType", mapAccessEmptyBenchmark[bigType]) +} -- cgit v1.3-5-g9baa