aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/map_benchmark_test.go
diff options
context:
space:
mode:
authorMartin Möhrmann <moehrmann@google.com>2018-04-27 21:58:59 +0200
committerMartin Möhrmann <moehrmann@google.com>2018-05-08 21:15:16 +0000
commitaee71dd70b3779c66950ce6a952deca13d48e55e (patch)
treeba5e077b2478755d5a423c9898c23b9bd3819cdd /src/runtime/map_benchmark_test.go
parentcd1976dbef0a4a474cccb9e7fcb1e9cf2310df66 (diff)
downloadgo-aee71dd70b3779c66950ce6a952deca13d48e55e.tar.gz
go-aee71dd70b3779c66950ce6a952deca13d48e55e.zip
cmd/compile: optimize map-clearing range idiom
replace map clears of the form: for k := range m { delete(m, k) } (where m is map with key type that is reflexive for ==) with a new runtime function that clears the maps backing array with a memclr and reinitializes the hmap struct. Map key types that for example contain floats are not replaced by this optimization since NaN keys cannot be deleted from maps using delete. name old time/op new time/op delta GoMapClear/Reflexive/1 92.2ns ± 1% 47.1ns ± 2% -48.89% (p=0.000 n=9+9) GoMapClear/Reflexive/10 108ns ± 1% 48ns ± 2% -55.68% (p=0.000 n=10+10) GoMapClear/Reflexive/100 303ns ± 2% 110ns ± 3% -63.56% (p=0.000 n=10+10) GoMapClear/Reflexive/1000 3.58µs ± 3% 1.23µs ± 2% -65.49% (p=0.000 n=9+10) GoMapClear/Reflexive/10000 28.2µs ± 3% 10.3µs ± 2% -63.55% (p=0.000 n=9+10) GoMapClear/NonReflexive/1 121ns ± 2% 124ns ± 7% ~ (p=0.097 n=10+10) GoMapClear/NonReflexive/10 137ns ± 2% 139ns ± 3% +1.53% (p=0.033 n=10+10) GoMapClear/NonReflexive/100 331ns ± 3% 334ns ± 2% ~ (p=0.342 n=10+10) GoMapClear/NonReflexive/1000 3.64µs ± 3% 3.64µs ± 2% ~ (p=0.887 n=9+10) GoMapClear/NonReflexive/10000 28.1µs ± 2% 28.4µs ± 3% ~ (p=0.247 n=10+10) Fixes #20138 Change-Id: I181332a8ef434a4f0d89659f492d8711db3f3213 Reviewed-on: https://go-review.googlesource.com/110055 Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/runtime/map_benchmark_test.go')
-rw-r--r--src/runtime/map_benchmark_test.go29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/runtime/map_benchmark_test.go b/src/runtime/map_benchmark_test.go
index aec0c51f3f..025c0398d3 100644
--- a/src/runtime/map_benchmark_test.go
+++ b/src/runtime/map_benchmark_test.go
@@ -341,3 +341,32 @@ func BenchmarkComplexAlgMap(b *testing.B) {
_ = m[k]
}
}
+
+func BenchmarkGoMapClear(b *testing.B) {
+ b.Run("Reflexive", func(b *testing.B) {
+ for size := 1; size < 100000; size *= 10 {
+ b.Run(strconv.Itoa(size), func(b *testing.B) {
+ m := make(map[int]int, size)
+ for i := 0; i < b.N; i++ {
+ m[0] = size // Add one element so len(m) != 0 avoiding fast paths.
+ for k := range m {
+ delete(m, k)
+ }
+ }
+ })
+ }
+ })
+ b.Run("NonReflexive", func(b *testing.B) {
+ for size := 1; size < 100000; size *= 10 {
+ b.Run(strconv.Itoa(size), func(b *testing.B) {
+ m := make(map[float64]int, size)
+ for i := 0; i < b.N; i++ {
+ m[1.0] = size // Add one element so len(m) != 0 avoiding fast paths.
+ for k := range m {
+ delete(m, k)
+ }
+ }
+ })
+ }
+ })
+}