1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
17 func BenchmarkHashStringSpeed(b
*testing
.B
) {
18 strings
:= make([]string, size
)
19 for i
:= 0; i
< size
; i
++ {
20 strings
[i
] = fmt
.Sprintf("string#%d", i
)
23 m
:= make(map[string]int, size
)
24 for i
:= 0; i
< size
; i
++ {
29 for i
:= 0; i
< b
.N
; i
++ {
30 sum
+= m
[strings
[idx
]]
40 func BenchmarkHashBytesSpeed(b
*testing
.B
) {
41 // a bunch of chunks, each with a different alignment mod 16
42 var chunks
[size
]chunk
43 // initialize each to a different value
44 for i
:= 0; i
< size
; i
++ {
45 chunks
[i
][0] = byte(i
)
48 m
:= make(map[chunk
]int, size
)
49 for i
, c
:= range chunks
{
54 for i
:= 0; i
< b
.N
; i
++ {
55 if m
[chunks
[idx
]] != idx
{
56 b
.Error("bad map entry for chunk")
65 func BenchmarkHashInt32Speed(b
*testing
.B
) {
66 ints
:= make([]int32, size
)
67 for i
:= 0; i
< size
; i
++ {
71 m
:= make(map[int32]int, size
)
72 for i
:= 0; i
< size
; i
++ {
77 for i
:= 0; i
< b
.N
; i
++ {
86 func BenchmarkHashInt64Speed(b
*testing
.B
) {
87 ints
:= make([]int64, size
)
88 for i
:= 0; i
< size
; i
++ {
92 m
:= make(map[int64]int, size
)
93 for i
:= 0; i
< size
; i
++ {
98 for i
:= 0; i
< b
.N
; i
++ {
106 func BenchmarkHashStringArraySpeed(b
*testing
.B
) {
107 stringpairs
:= make([][2]string, size
)
108 for i
:= 0; i
< size
; i
++ {
109 for j
:= 0; j
< 2; j
++ {
110 stringpairs
[i
][j
] = fmt
.Sprintf("string#%d/%d", i
, j
)
114 m
:= make(map[[2]string]int, size
)
115 for i
:= 0; i
< size
; i
++ {
116 m
[stringpairs
[i
]] = 0
120 for i
:= 0; i
< b
.N
; i
++ {
121 sum
+= m
[stringpairs
[idx
]]
129 func BenchmarkMegMap(b
*testing
.B
) {
130 m
:= make(map[string]bool)
131 for suffix
:= 'A'; suffix
<= 'G'; suffix
++ {
132 m
[strings
.Repeat("X", 1<<20-1)+fmt
.Sprint(suffix
)] = true
134 key
:= strings
.Repeat("X", 1<<20-1) + "k"
136 for i
:= 0; i
< b
.N
; i
++ {
141 func BenchmarkMegOneMap(b
*testing
.B
) {
142 m
:= make(map[string]bool)
143 m
[strings
.Repeat("X", 1<<20)] = true
144 key
:= strings
.Repeat("Y", 1<<20)
146 for i
:= 0; i
< b
.N
; i
++ {
151 func BenchmarkMegEqMap(b
*testing
.B
) {
152 m
:= make(map[string]bool)
153 key1
:= strings
.Repeat("X", 1<<20)
154 key2
:= strings
.Repeat("X", 1<<20) // equal but different instance
157 for i
:= 0; i
< b
.N
; i
++ {
162 func BenchmarkMegEmptyMap(b
*testing
.B
) {
163 m
:= make(map[string]bool)
164 key
:= strings
.Repeat("X", 1<<20)
166 for i
:= 0; i
< b
.N
; i
++ {
171 func BenchmarkSmallStrMap(b
*testing
.B
) {
172 m
:= make(map[string]bool)
173 for suffix
:= 'A'; suffix
<= 'G'; suffix
++ {
174 m
[fmt
.Sprint(suffix
)] = true
178 for i
:= 0; i
< b
.N
; i
++ {
183 func BenchmarkMapStringKeysEight_16(b
*testing
.B
) { benchmarkMapStringKeysEight(b
, 16) }
184 func BenchmarkMapStringKeysEight_32(b
*testing
.B
) { benchmarkMapStringKeysEight(b
, 32) }
185 func BenchmarkMapStringKeysEight_64(b
*testing
.B
) { benchmarkMapStringKeysEight(b
, 64) }
186 func BenchmarkMapStringKeysEight_1M(b
*testing
.B
) { benchmarkMapStringKeysEight(b
, 1<<20) }
188 func benchmarkMapStringKeysEight(b
*testing
.B
, keySize
int) {
189 m
:= make(map[string]bool)
190 for i
:= 0; i
< 8; i
++ {
191 m
[strings
.Repeat("K", i
+1)] = true
193 key
:= strings
.Repeat("K", keySize
)
195 for i
:= 0; i
< b
.N
; i
++ {
200 func BenchmarkIntMap(b
*testing
.B
) {
201 m
:= make(map[int]bool)
202 for i
:= 0; i
< 8; i
++ {
206 for i
:= 0; i
< b
.N
; i
++ {
211 func BenchmarkMapFirst(b
*testing
.B
) {
212 for n
:= 1; n
<= 16; n
++ {
213 b
.Run(fmt
.Sprintf("%d", n
), func(b
*testing
.B
) {
214 m
:= make(map[int]bool)
215 for i
:= 0; i
< n
; i
++ {
219 for i
:= 0; i
< b
.N
; i
++ {
225 func BenchmarkMapMid(b
*testing
.B
) {
226 for n
:= 1; n
<= 16; n
++ {
227 b
.Run(fmt
.Sprintf("%d", n
), func(b
*testing
.B
) {
228 m
:= make(map[int]bool)
229 for i
:= 0; i
< n
; i
++ {
233 for i
:= 0; i
< b
.N
; i
++ {
239 func BenchmarkMapLast(b
*testing
.B
) {
240 for n
:= 1; n
<= 16; n
++ {
241 b
.Run(fmt
.Sprintf("%d", n
), func(b
*testing
.B
) {
242 m
:= make(map[int]bool)
243 for i
:= 0; i
< n
; i
++ {
247 for i
:= 0; i
< b
.N
; i
++ {
254 func BenchmarkMapCycle(b
*testing
.B
) {
255 // Arrange map entries to be a permutation, so that
256 // we hit all entries, and one lookup is data dependent
257 // on the previous lookup.
259 p
:= rand
.New(rand
.NewSource(1)).Perm(N
)
261 for i
:= 0; i
< N
; i
++ {
266 for i
:= 0; i
< b
.N
; i
++ {
272 // Accessing the same keys in a row.
273 func benchmarkRepeatedLookup(b
*testing
.B
, lookupKeySize
int) {
274 m
:= make(map[string]bool)
275 // At least bigger than a single bucket:
276 for i
:= 0; i
< 64; i
++ {
277 m
[fmt
.Sprintf("some key %d", i
)] = true
279 base
:= strings
.Repeat("x", lookupKeySize
-1)
283 for i
:= 0; i
< b
.N
/4; i
++ {
291 func BenchmarkRepeatedLookupStrMapKey32(b
*testing
.B
) { benchmarkRepeatedLookup(b
, 32) }
292 func BenchmarkRepeatedLookupStrMapKey1M(b
*testing
.B
) { benchmarkRepeatedLookup(b
, 1<<20) }
294 func BenchmarkMakeMap(b
*testing
.B
) {
295 b
.Run("[Byte]Byte", func(b
*testing
.B
) {
297 for i
:= 0; i
< b
.N
; i
++ {
298 m
= make(map[byte]byte, 10)
302 b
.Run("[Int]Int", func(b
*testing
.B
) {
304 for i
:= 0; i
< b
.N
; i
++ {
305 m
= make(map[int]int, 10)
311 func BenchmarkNewEmptyMap(b
*testing
.B
) {
313 for i
:= 0; i
< b
.N
; i
++ {
314 _
= make(map[int]int)
318 func BenchmarkNewSmallMap(b
*testing
.B
) {
320 for i
:= 0; i
< b
.N
; i
++ {
321 m
:= make(map[int]int)
327 func BenchmarkMapIter(b
*testing
.B
) {
328 m
:= make(map[int]bool)
329 for i
:= 0; i
< 8; i
++ {
333 for i
:= 0; i
< b
.N
; i
++ {
339 func BenchmarkMapIterEmpty(b
*testing
.B
) {
340 m
:= make(map[int]bool)
342 for i
:= 0; i
< b
.N
; i
++ {
348 func BenchmarkSameLengthMap(b
*testing
.B
) {
349 // long strings, same length, differ in first few
350 // and last few bytes.
351 m
:= make(map[string]bool)
352 s1
:= "foo" + strings
.Repeat("-", 100) + "bar"
353 s2
:= "goo" + strings
.Repeat("-", 100) + "ber"
357 for i
:= 0; i
< b
.N
; i
++ {
364 func BenchmarkBigKeyMap(b
*testing
.B
) {
365 m
:= make(map[BigKey
]bool)
368 for i
:= 0; i
< b
.N
; i
++ {
375 func BenchmarkBigValMap(b
*testing
.B
) {
376 m
:= make(map[BigKey
]BigVal
)
378 m
[k
] = BigVal
{6, 7, 8}
379 for i
:= 0; i
< b
.N
; i
++ {
384 func BenchmarkSmallKeyMap(b
*testing
.B
) {
385 m
:= make(map[int16]bool)
387 for i
:= 0; i
< b
.N
; i
++ {
392 func BenchmarkMapPopulate(b
*testing
.B
) {
393 for size
:= 1; size
< 1000000; size
*= 10 {
394 b
.Run(strconv
.Itoa(size
), func(b
*testing
.B
) {
396 for i
:= 0; i
< b
.N
; i
++ {
397 m
:= make(map[int]bool)
398 for j
:= 0; j
< size
; j
++ {
406 type ComplexAlgKey
struct {
416 func BenchmarkComplexAlgMap(b
*testing
.B
) {
417 m
:= make(map[ComplexAlgKey
]bool)
420 for i
:= 0; i
< b
.N
; i
++ {
425 func BenchmarkGoMapClear(b
*testing
.B
) {
426 b
.Run("Reflexive", func(b
*testing
.B
) {
427 for size
:= 1; size
< 100000; size
*= 10 {
428 b
.Run(strconv
.Itoa(size
), func(b
*testing
.B
) {
429 m
:= make(map[int]int, size
)
430 for i
:= 0; i
< b
.N
; i
++ {
431 m
[0] = size
// Add one element so len(m) != 0 avoiding fast paths.
439 b
.Run("NonReflexive", func(b
*testing
.B
) {
440 for size
:= 1; size
< 100000; size
*= 10 {
441 b
.Run(strconv
.Itoa(size
), func(b
*testing
.B
) {
442 m
:= make(map[float64]int, size
)
443 for i
:= 0; i
< b
.N
; i
++ {
444 m
[1.0] = size
// Add one element so len(m) != 0 avoiding fast paths.
454 func BenchmarkMapStringConversion(b
*testing
.B
) {
455 for _
, length
:= range []int{32, 64} {
456 b
.Run(strconv
.Itoa(length
), func(b
*testing
.B
) {
457 bytes
:= make([]byte, length
)
458 b
.Run("simple", func(b
*testing
.B
) {
460 m
:= make(map[string]int)
462 for i
:= 0; i
< b
.N
; i
++ {
466 b
.Run("struct", func(b
*testing
.B
) {
468 type stringstruct
struct{ s
string }
469 m
:= make(map[stringstruct
]int)
470 m
[stringstruct
{string(bytes
)}] = 0
471 for i
:= 0; i
< b
.N
; i
++ {
472 _
= m
[stringstruct
{string(bytes
)}]
475 b
.Run("array", func(b
*testing
.B
) {
477 type stringarray
[1]string
478 m
:= make(map[stringarray
]int)
479 m
[stringarray
{string(bytes
)}] = 0
480 for i
:= 0; i
< b
.N
; i
++ {
481 _
= m
[stringarray
{string(bytes
)}]
490 func BenchmarkMapInterfaceString(b
*testing
.B
) {
493 for i
:= 0; i
< 100; i
++ {
494 m
[fmt
.Sprintf("%d", i
)] = true
499 for i
:= 0; i
< b
.N
; i
++ {
503 func BenchmarkMapInterfacePtr(b
*testing
.B
) {
506 for i
:= 0; i
< 100; i
++ {
513 for i
:= 0; i
< b
.N
; i
++ {
520 hintGreaterThan8
= 32
523 func BenchmarkNewEmptyMapHintLessThan8(b
*testing
.B
) {
525 for i
:= 0; i
< b
.N
; i
++ {
526 _
= make(map[int]int, hintLessThan8
)
530 func BenchmarkNewEmptyMapHintGreaterThan8(b
*testing
.B
) {
532 for i
:= 0; i
< b
.N
; i
++ {
533 _
= make(map[int]int, hintGreaterThan8
)