github.com/fenixara/go@v0.0.0-20170127160404-96ea0918e670/src/runtime/mapspeed_test.go (about)

     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.
     4  package runtime_test
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  	"testing"
    10  )
    11  
    12  const size = 10
    13  
    14  func BenchmarkHashStringSpeed(b *testing.B) {
    15  	strings := make([]string, size)
    16  	for i := 0; i < size; i++ {
    17  		strings[i] = fmt.Sprintf("string#%d", i)
    18  	}
    19  	sum := 0
    20  	m := make(map[string]int, size)
    21  	for i := 0; i < size; i++ {
    22  		m[strings[i]] = 0
    23  	}
    24  	idx := 0
    25  	b.ResetTimer()
    26  	for i := 0; i < b.N; i++ {
    27  		sum += m[strings[idx]]
    28  		idx++
    29  		if idx == size {
    30  			idx = 0
    31  		}
    32  	}
    33  }
    34  
    35  type chunk [17]byte
    36  
    37  func BenchmarkHashBytesSpeed(b *testing.B) {
    38  	// a bunch of chunks, each with a different alignment mod 16
    39  	var chunks [size]chunk
    40  	// initialize each to a different value
    41  	for i := 0; i < size; i++ {
    42  		chunks[i][0] = byte(i)
    43  	}
    44  	// put into a map
    45  	m := make(map[chunk]int, size)
    46  	for i, c := range chunks {
    47  		m[c] = i
    48  	}
    49  	idx := 0
    50  	b.ResetTimer()
    51  	for i := 0; i < b.N; i++ {
    52  		if m[chunks[idx]] != idx {
    53  			b.Error("bad map entry for chunk")
    54  		}
    55  		idx++
    56  		if idx == size {
    57  			idx = 0
    58  		}
    59  	}
    60  }
    61  
    62  func BenchmarkHashInt32Speed(b *testing.B) {
    63  	ints := make([]int32, size)
    64  	for i := 0; i < size; i++ {
    65  		ints[i] = int32(i)
    66  	}
    67  	sum := 0
    68  	m := make(map[int32]int, size)
    69  	for i := 0; i < size; i++ {
    70  		m[ints[i]] = 0
    71  	}
    72  	idx := 0
    73  	b.ResetTimer()
    74  	for i := 0; i < b.N; i++ {
    75  		sum += m[ints[idx]]
    76  		idx++
    77  		if idx == size {
    78  			idx = 0
    79  		}
    80  	}
    81  }
    82  
    83  func BenchmarkHashInt64Speed(b *testing.B) {
    84  	ints := make([]int64, size)
    85  	for i := 0; i < size; i++ {
    86  		ints[i] = int64(i)
    87  	}
    88  	sum := 0
    89  	m := make(map[int64]int, size)
    90  	for i := 0; i < size; i++ {
    91  		m[ints[i]] = 0
    92  	}
    93  	idx := 0
    94  	b.ResetTimer()
    95  	for i := 0; i < b.N; i++ {
    96  		sum += m[ints[idx]]
    97  		idx++
    98  		if idx == size {
    99  			idx = 0
   100  		}
   101  	}
   102  }
   103  func BenchmarkHashStringArraySpeed(b *testing.B) {
   104  	stringpairs := make([][2]string, size)
   105  	for i := 0; i < size; i++ {
   106  		for j := 0; j < 2; j++ {
   107  			stringpairs[i][j] = fmt.Sprintf("string#%d/%d", i, j)
   108  		}
   109  	}
   110  	sum := 0
   111  	m := make(map[[2]string]int, size)
   112  	for i := 0; i < size; i++ {
   113  		m[stringpairs[i]] = 0
   114  	}
   115  	idx := 0
   116  	b.ResetTimer()
   117  	for i := 0; i < b.N; i++ {
   118  		sum += m[stringpairs[idx]]
   119  		idx++
   120  		if idx == size {
   121  			idx = 0
   122  		}
   123  	}
   124  }
   125  
   126  func BenchmarkMegMap(b *testing.B) {
   127  	m := make(map[string]bool)
   128  	for suffix := 'A'; suffix <= 'G'; suffix++ {
   129  		m[strings.Repeat("X", 1<<20-1)+fmt.Sprint(suffix)] = true
   130  	}
   131  	key := strings.Repeat("X", 1<<20-1) + "k"
   132  	b.ResetTimer()
   133  	for i := 0; i < b.N; i++ {
   134  		_, _ = m[key]
   135  	}
   136  }
   137  
   138  func BenchmarkMegOneMap(b *testing.B) {
   139  	m := make(map[string]bool)
   140  	m[strings.Repeat("X", 1<<20)] = true
   141  	key := strings.Repeat("Y", 1<<20)
   142  	b.ResetTimer()
   143  	for i := 0; i < b.N; i++ {
   144  		_, _ = m[key]
   145  	}
   146  }
   147  
   148  func BenchmarkMegEqMap(b *testing.B) {
   149  	m := make(map[string]bool)
   150  	key1 := strings.Repeat("X", 1<<20)
   151  	key2 := strings.Repeat("X", 1<<20) // equal but different instance
   152  	m[key1] = true
   153  	b.ResetTimer()
   154  	for i := 0; i < b.N; i++ {
   155  		_, _ = m[key2]
   156  	}
   157  }
   158  
   159  func BenchmarkMegEmptyMap(b *testing.B) {
   160  	m := make(map[string]bool)
   161  	key := strings.Repeat("X", 1<<20)
   162  	b.ResetTimer()
   163  	for i := 0; i < b.N; i++ {
   164  		_, _ = m[key]
   165  	}
   166  }
   167  
   168  func BenchmarkSmallStrMap(b *testing.B) {
   169  	m := make(map[string]bool)
   170  	for suffix := 'A'; suffix <= 'G'; suffix++ {
   171  		m[fmt.Sprint(suffix)] = true
   172  	}
   173  	key := "k"
   174  	b.ResetTimer()
   175  	for i := 0; i < b.N; i++ {
   176  		_, _ = m[key]
   177  	}
   178  }
   179  
   180  func BenchmarkMapStringKeysEight_16(b *testing.B) { benchmarkMapStringKeysEight(b, 16) }
   181  func BenchmarkMapStringKeysEight_32(b *testing.B) { benchmarkMapStringKeysEight(b, 32) }
   182  func BenchmarkMapStringKeysEight_64(b *testing.B) { benchmarkMapStringKeysEight(b, 64) }
   183  func BenchmarkMapStringKeysEight_1M(b *testing.B) { benchmarkMapStringKeysEight(b, 1<<20) }
   184  
   185  func benchmarkMapStringKeysEight(b *testing.B, keySize int) {
   186  	m := make(map[string]bool)
   187  	for i := 0; i < 8; i++ {
   188  		m[strings.Repeat("K", i+1)] = true
   189  	}
   190  	key := strings.Repeat("K", keySize)
   191  	b.ResetTimer()
   192  	for i := 0; i < b.N; i++ {
   193  		_ = m[key]
   194  	}
   195  }
   196  
   197  func BenchmarkIntMap(b *testing.B) {
   198  	m := make(map[int]bool)
   199  	for i := 0; i < 8; i++ {
   200  		m[i] = true
   201  	}
   202  	b.ResetTimer()
   203  	for i := 0; i < b.N; i++ {
   204  		_, _ = m[7]
   205  	}
   206  }
   207  
   208  // Accessing the same keys in a row.
   209  func benchmarkRepeatedLookup(b *testing.B, lookupKeySize int) {
   210  	m := make(map[string]bool)
   211  	// At least bigger than a single bucket:
   212  	for i := 0; i < 64; i++ {
   213  		m[fmt.Sprintf("some key %d", i)] = true
   214  	}
   215  	base := strings.Repeat("x", lookupKeySize-1)
   216  	key1 := base + "1"
   217  	key2 := base + "2"
   218  	b.ResetTimer()
   219  	for i := 0; i < b.N/4; i++ {
   220  		_ = m[key1]
   221  		_ = m[key1]
   222  		_ = m[key2]
   223  		_ = m[key2]
   224  	}
   225  }
   226  
   227  func BenchmarkRepeatedLookupStrMapKey32(b *testing.B) { benchmarkRepeatedLookup(b, 32) }
   228  func BenchmarkRepeatedLookupStrMapKey1M(b *testing.B) { benchmarkRepeatedLookup(b, 1<<20) }
   229  
   230  func BenchmarkNewEmptyMap(b *testing.B) {
   231  	b.ReportAllocs()
   232  	for i := 0; i < b.N; i++ {
   233  		_ = make(map[int]int)
   234  	}
   235  }
   236  
   237  func BenchmarkNewSmallMap(b *testing.B) {
   238  	b.ReportAllocs()
   239  	for i := 0; i < b.N; i++ {
   240  		m := make(map[int]int)
   241  		m[0] = 0
   242  		m[1] = 1
   243  	}
   244  }
   245  
   246  func BenchmarkMapIter(b *testing.B) {
   247  	m := make(map[int]bool)
   248  	for i := 0; i < 8; i++ {
   249  		m[i] = true
   250  	}
   251  	b.ResetTimer()
   252  	for i := 0; i < b.N; i++ {
   253  		for range m {
   254  		}
   255  	}
   256  }
   257  
   258  func BenchmarkMapIterEmpty(b *testing.B) {
   259  	m := make(map[int]bool)
   260  	b.ResetTimer()
   261  	for i := 0; i < b.N; i++ {
   262  		for range m {
   263  		}
   264  	}
   265  }
   266  
   267  func BenchmarkSameLengthMap(b *testing.B) {
   268  	// long strings, same length, differ in first few
   269  	// and last few bytes.
   270  	m := make(map[string]bool)
   271  	s1 := "foo" + strings.Repeat("-", 100) + "bar"
   272  	s2 := "goo" + strings.Repeat("-", 100) + "ber"
   273  	m[s1] = true
   274  	m[s2] = true
   275  	b.ResetTimer()
   276  	for i := 0; i < b.N; i++ {
   277  		_ = m[s1]
   278  	}
   279  }
   280  
   281  type BigKey [3]int64
   282  
   283  func BenchmarkBigKeyMap(b *testing.B) {
   284  	m := make(map[BigKey]bool)
   285  	k := BigKey{3, 4, 5}
   286  	m[k] = true
   287  	for i := 0; i < b.N; i++ {
   288  		_ = m[k]
   289  	}
   290  }
   291  
   292  type BigVal [3]int64
   293  
   294  func BenchmarkBigValMap(b *testing.B) {
   295  	m := make(map[BigKey]BigVal)
   296  	k := BigKey{3, 4, 5}
   297  	m[k] = BigVal{6, 7, 8}
   298  	for i := 0; i < b.N; i++ {
   299  		_ = m[k]
   300  	}
   301  }
   302  
   303  func BenchmarkSmallKeyMap(b *testing.B) {
   304  	m := make(map[int16]bool)
   305  	m[5] = true
   306  	for i := 0; i < b.N; i++ {
   307  		_ = m[5]
   308  	}
   309  }
   310  
   311  type ComplexAlgKey struct {
   312  	a, b, c int64
   313  	_       int
   314  	d       int32
   315  	_       int
   316  	e       string
   317  	_       int
   318  	f, g, h int64
   319  }
   320  
   321  func BenchmarkComplexAlgMap(b *testing.B) {
   322  	m := make(map[ComplexAlgKey]bool)
   323  	var k ComplexAlgKey
   324  	m[k] = true
   325  	for i := 0; i < b.N; i++ {
   326  		_ = m[k]
   327  	}
   328  }