github.com/iainanderson83/datastructures@v0.0.4-0.20191103204413-889e20b53bcf/hashmap/hashmap_test.go (about) 1 package hashmap 2 3 import ( 4 "math/rand" 5 "sync" 6 "testing" 7 ) 8 9 var ( 10 redistributionTuples = []entry{} 11 ) 12 13 func TestMain(m *testing.M) { 14 rand.Seed(42) 15 16 ma := make(map[string]struct{}) 17 18 var i int 19 for { 20 key := wordList[rand.Intn(len(wordList))] 21 if _, ok := ma[key]; ok { 22 continue 23 } 24 ma[key] = struct{}{} 25 tpl := entry{key: key, value: wordList[rand.Intn(len(wordList))]} 26 redistributionTuples = append(redistributionTuples, tpl) 27 28 i++ 29 if i > 50 { 30 break 31 } 32 } 33 34 m.Run() 35 } 36 37 func TestMap(t *testing.T) { 38 tests := map[string]struct { 39 debug bool 40 adds []entry 41 lookups []entry 42 }{ 43 "SingleValue": { 44 false, 45 []entry{{key: "hello", value: "world"}}, 46 []entry{{key: "hello", value: "world"}}, 47 }, 48 "OverwriteValue": { 49 false, 50 []entry{{key: "hello", value: "world"}, {key: "hello", value: "foo"}}, 51 []entry{{key: "hello", value: "foo"}}, 52 }, 53 "MultipleValues": { 54 false, 55 []entry{{key: "hello", value: "world"}, {key: "foo", value: "bar"}, {key: "baz", value: "bubbles"}, {key: "hello", value: "foo"}}, 56 []entry{{key: "foo", value: "bar"}, {key: "baz", value: "bubbles"}, {key: "hello", value: "foo"}}, 57 }, 58 "Redistribute": { 59 false, 60 redistributionTuples, 61 redistributionTuples, 62 }, 63 } 64 65 for name, test := range tests { 66 t.Run(name, func(t *testing.T) { 67 m := NewFNV1aHashmap() 68 m2 := NewRuntimeHashmap() 69 for _, tpl := range test.adds { 70 m.Add(tpl.key, tpl.value) 71 m2.Add(tpl.key, tpl.value) 72 } 73 74 for _, tpl := range test.lookups { 75 v, _ := m.Lookup(tpl.key) 76 if v != tpl.value { 77 t.Fatalf("%s: expected '%v', got '%v'", tpl.key, tpl.value, v) 78 } 79 80 v2, _ := m2.Lookup(tpl.key) 81 if v2 != tpl.value { 82 t.Fatalf("%s: expected '%v', got '%v'", tpl.key, tpl.value, v2) 83 } 84 } 85 }) 86 } 87 } 88 89 func BenchmarkRuntimeHashmap(b *testing.B) { 90 b.ReportAllocs() 91 92 for i := 0; i < b.N; i++ { 93 m := NewRuntimeHashmap() 94 for _, tpl := range redistributionTuples { 95 m.Add(tpl.key, tpl.value) 96 } 97 98 for _, tpl := range redistributionTuples { 99 v, _ := m.Lookup(tpl.key) 100 _ = v 101 } 102 } 103 } 104 105 func BenchmarkFNV1aHashmap(b *testing.B) { 106 b.ReportAllocs() 107 108 for i := 0; i < b.N; i++ { 109 m := NewFNV1aHashmap() 110 for _, tpl := range redistributionTuples { 111 m.Add(tpl.key, tpl.value) 112 } 113 114 for _, tpl := range redistributionTuples { 115 v, _ := m.Lookup(tpl.key) 116 _ = v 117 } 118 } 119 } 120 121 func BenchmarkGoHashmap(b *testing.B) { 122 b.ReportAllocs() 123 124 for i := 0; i < b.N; i++ { 125 m := make(map[string]interface{}) 126 for _, tpl := range redistributionTuples { 127 m[tpl.key] = tpl.value 128 } 129 130 for _, tpl := range redistributionTuples { 131 v := m[tpl.key] 132 _ = v 133 } 134 } 135 } 136 137 func BenchmarkXXHashmap(b *testing.B) { 138 b.ReportAllocs() 139 140 for i := 0; i < b.N; i++ { 141 m := NewXXHashmap() 142 for _, tpl := range redistributionTuples { 143 m.Add(tpl.key, tpl.value) 144 } 145 146 for _, tpl := range redistributionTuples { 147 v, _ := m.Lookup(tpl.key) 148 _ = v 149 } 150 } 151 } 152 153 func BenchmarkGoSyncMap(b *testing.B) { 154 b.ReportAllocs() 155 156 for i := 0; i < b.N; i++ { 157 m := &sync.Map{} 158 for _, tpl := range redistributionTuples { 159 m.Store(tpl.key, tpl.value) 160 } 161 162 for _, tpl := range redistributionTuples { 163 v, _ := m.Load(tpl.key) 164 _ = v 165 } 166 } 167 }