github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/cmap/cmap_bench_test.go (about) 1 package cmap 2 3 import ( 4 "strconv" 5 "sync" 6 "testing" 7 ) 8 9 func BenchmarkItems(b *testing.B) { 10 m := New() 11 12 // Insert 100 elements. 13 for i := 0; i < 10000; i++ { 14 m.Set(strconv.Itoa(i), animal{strconv.Itoa(i)}) 15 } 16 for i := 0; i < b.N; i++ { 17 m.Items() 18 } 19 } 20 21 func BenchmarkMarshalJson(b *testing.B) { 22 m := New() 23 24 // Insert 100 elements. 25 for i := 0; i < 10000; i++ { 26 m.Set(strconv.Itoa(i), animal{strconv.Itoa(i)}) 27 } 28 for i := 0; i < b.N; i++ { 29 _, err := m.MarshalJSON() 30 if err != nil { 31 b.FailNow() 32 } 33 } 34 } 35 36 func BenchmarkStrconv(b *testing.B) { 37 for i := 0; i < b.N; i++ { 38 strconv.Itoa(i) 39 } 40 } 41 42 func BenchmarkSingleInsertAbsent(b *testing.B) { 43 m := New() 44 b.ResetTimer() 45 for i := 0; i < b.N; i++ { 46 m.Set(strconv.Itoa(i), "value") 47 } 48 } 49 50 func BenchmarkSingleInsertAbsentSyncMap(b *testing.B) { 51 var m sync.Map 52 b.ResetTimer() 53 for i := 0; i < b.N; i++ { 54 m.Store(strconv.Itoa(i), "value") 55 } 56 } 57 58 func BenchmarkSingleInsertPresent(b *testing.B) { 59 m := New() 60 m.Set("key", "value") 61 b.ResetTimer() 62 for i := 0; i < b.N; i++ { 63 m.Set("key", "value") 64 } 65 } 66 67 func BenchmarkSingleInsertPresentSyncMap(b *testing.B) { 68 var m sync.Map 69 m.Store("key", "value") 70 b.ResetTimer() 71 for i := 0; i < b.N; i++ { 72 m.Store("key", "value") 73 } 74 } 75 76 func benchmarkMultiInsertDifferent(shardsCount int, b *testing.B) { 77 m := New(WithShardCount(shardsCount)) 78 finished := make(chan struct{}, b.N) 79 _, set := GetSet(m, finished) 80 b.ResetTimer() 81 for i := 0; i < b.N; i++ { 82 go set(strconv.Itoa(i), "value") 83 } 84 for i := 0; i < b.N; i++ { 85 <-finished 86 } 87 } 88 89 func BenchmarkMultiInsertDifferentSyncMap(b *testing.B) { 90 var m sync.Map 91 finished := make(chan struct{}, b.N) 92 _, set := GetSetSyncMap(&m, finished) 93 94 b.ResetTimer() 95 for i := 0; i < b.N; i++ { 96 go set(strconv.Itoa(i), "value") 97 } 98 for i := 0; i < b.N; i++ { 99 <-finished 100 } 101 } 102 103 func BenchmarkMultiInsertDifferent_1_Shard(b *testing.B) { 104 runWithShards(benchmarkMultiInsertDifferent, b, 1) 105 } 106 107 func BenchmarkMultiInsertDifferent_16_Shard(b *testing.B) { 108 runWithShards(benchmarkMultiInsertDifferent, b, 16) 109 } 110 111 func BenchmarkMultiInsertDifferent_32_Shard(b *testing.B) { 112 runWithShards(benchmarkMultiInsertDifferent, b, 32) 113 } 114 115 func BenchmarkMultiInsertDifferent_256_Shard(b *testing.B) { 116 runWithShards(benchmarkMultiGetSetDifferent, b, 256) 117 } 118 119 func BenchmarkMultiInsertSame(b *testing.B) { 120 m := New() 121 finished := make(chan struct{}, b.N) 122 _, set := GetSet(m, finished) 123 m.Set("key", "value") 124 b.ResetTimer() 125 for i := 0; i < b.N; i++ { 126 go set("key", "value") 127 } 128 for i := 0; i < b.N; i++ { 129 <-finished 130 } 131 } 132 133 func BenchmarkMultiInsertSameSyncMap(b *testing.B) { 134 var m sync.Map 135 finished := make(chan struct{}, b.N) 136 _, set := GetSetSyncMap(&m, finished) 137 m.Store("key", "value") 138 b.ResetTimer() 139 for i := 0; i < b.N; i++ { 140 go set("key", "value") 141 } 142 for i := 0; i < b.N; i++ { 143 <-finished 144 } 145 } 146 147 func BenchmarkMultiGetSame(b *testing.B) { 148 m := New() 149 finished := make(chan struct{}, b.N) 150 get, _ := GetSet(m, finished) 151 m.Set("key", "value") 152 b.ResetTimer() 153 for i := 0; i < b.N; i++ { 154 go get("key", "value") 155 } 156 for i := 0; i < b.N; i++ { 157 <-finished 158 } 159 } 160 161 func BenchmarkMultiGetSameSyncMap(b *testing.B) { 162 var m sync.Map 163 finished := make(chan struct{}, b.N) 164 get, _ := GetSetSyncMap(&m, finished) 165 m.Store("key", "value") 166 b.ResetTimer() 167 for i := 0; i < b.N; i++ { 168 go get("key", "value") 169 } 170 for i := 0; i < b.N; i++ { 171 <-finished 172 } 173 } 174 175 func benchmarkMultiGetSetDifferent(shardsCount int, b *testing.B) { 176 m := New(WithShardCount(shardsCount)) 177 finished := make(chan struct{}, 2*b.N) 178 get, set := GetSet(m, finished) 179 m.Set("-1", "value") 180 b.ResetTimer() 181 for i := 0; i < b.N; i++ { 182 go set(strconv.Itoa(i-1), "value") 183 go get(strconv.Itoa(i), "value") 184 } 185 for i := 0; i < 2*b.N; i++ { 186 <-finished 187 } 188 } 189 190 func BenchmarkMultiGetSetDifferentSyncMap(b *testing.B) { 191 var m sync.Map 192 finished := make(chan struct{}, 2*b.N) 193 get, set := GetSetSyncMap(&m, finished) 194 m.Store("-1", "value") 195 b.ResetTimer() 196 for i := 0; i < b.N; i++ { 197 go set(strconv.Itoa(i-1), "value") 198 go get(strconv.Itoa(i), "value") 199 } 200 for i := 0; i < 2*b.N; i++ { 201 <-finished 202 } 203 } 204 205 func BenchmarkMultiGetSetDifferent_1_Shard(b *testing.B) { 206 runWithShards(benchmarkMultiGetSetDifferent, b, 1) 207 } 208 209 func BenchmarkMultiGetSetDifferent_16_Shard(b *testing.B) { 210 runWithShards(benchmarkMultiGetSetDifferent, b, 16) 211 } 212 213 func BenchmarkMultiGetSetDifferent_32_Shard(b *testing.B) { 214 runWithShards(benchmarkMultiGetSetDifferent, b, 32) 215 } 216 217 func BenchmarkMultiGetSetDifferent_256_Shard(b *testing.B) { 218 runWithShards(benchmarkMultiGetSetDifferent, b, 256) 219 } 220 221 func benchmarkMultiGetSetBlock(shardsCount int, b *testing.B) { 222 m := New(WithShardCount(shardsCount)) 223 finished := make(chan struct{}, 2*b.N) 224 get, set := GetSet(m, finished) 225 for i := 0; i < b.N; i++ { 226 m.Set(strconv.Itoa(i%100), "value") 227 } 228 b.ResetTimer() 229 for i := 0; i < b.N; i++ { 230 go set(strconv.Itoa(i%100), "value") 231 go get(strconv.Itoa(i%100), "value") 232 } 233 for i := 0; i < 2*b.N; i++ { 234 <-finished 235 } 236 } 237 238 func BenchmarkMultiGetSetBlockSyncMap(b *testing.B) { 239 var m sync.Map 240 finished := make(chan struct{}, 2*b.N) 241 get, set := GetSetSyncMap(&m, finished) 242 for i := 0; i < b.N; i++ { 243 m.Store(strconv.Itoa(i%100), "value") 244 } 245 b.ResetTimer() 246 for i := 0; i < b.N; i++ { 247 go set(strconv.Itoa(i%100), "value") 248 go get(strconv.Itoa(i%100), "value") 249 } 250 for i := 0; i < 2*b.N; i++ { 251 <-finished 252 } 253 } 254 255 func BenchmarkMultiGetSetBlock_1_Shard(b *testing.B) { 256 runWithShards(benchmarkMultiGetSetBlock, b, 1) 257 } 258 259 func BenchmarkMultiGetSetBlock_16_Shard(b *testing.B) { 260 runWithShards(benchmarkMultiGetSetBlock, b, 16) 261 } 262 263 func BenchmarkMultiGetSetBlock_32_Shard(b *testing.B) { 264 runWithShards(benchmarkMultiGetSetBlock, b, 32) 265 } 266 267 func BenchmarkMultiGetSetBlock_256_Shard(b *testing.B) { 268 runWithShards(benchmarkMultiGetSetBlock, b, 256) 269 } 270 271 func GetSet(m *Map, finished chan struct{}) (set func(key, value string), get func(key, value string)) { 272 return func(key, value string) { 273 for i := 0; i < 10; i++ { 274 m.Get(key) 275 } 276 finished <- struct{}{} 277 }, func(key, value string) { 278 for i := 0; i < 10; i++ { 279 m.Set(key, value) 280 } 281 finished <- struct{}{} 282 } 283 } 284 285 func GetSetSyncMap(m *sync.Map, finished chan struct{}) (get func(key, value string), set func(key, value string)) { 286 get = func(key, value string) { 287 for i := 0; i < 10; i++ { 288 m.Load(key) 289 } 290 finished <- struct{}{} 291 } 292 set = func(key, value string) { 293 for i := 0; i < 10; i++ { 294 m.Store(key, value) 295 } 296 finished <- struct{}{} 297 } 298 return 299 } 300 301 func runWithShards(bench func(shardsCount int, b *testing.B), b *testing.B, shardsCount int) { 302 bench(shardsCount, b) 303 } 304 305 func BenchmarkKeys(b *testing.B) { 306 m := New() 307 308 // Insert 100 elements. 309 for i := 0; i < 10000; i++ { 310 m.Set(strconv.Itoa(i), animal{strconv.Itoa(i)}) 311 } 312 for i := 0; i < b.N; i++ { 313 m.Keys() 314 } 315 }