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