v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/hashtable/table_test.go (about) 1 package hashtable_test 2 3 import ( 4 "runtime" 5 "strconv" 6 "sync" 7 "testing" 8 9 "v8.run/go/exp/fastrand" 10 "v8.run/go/exp/hash" 11 "v8.run/go/exp/hashtable" 12 "v8.run/go/exp/util/slice" 13 ) 14 15 const size = 1 << 20 16 17 var keys []string = func() []string { 18 k := make([]string, size) 19 for i := range k { 20 k[i] = strconv.Itoa(i * 10000) 21 } 22 return k 23 }() 24 25 func TestTableInsert(t *testing.T) { 26 table := hashtable.New[string, string](1, hash.MemHashString64) 27 cpus := runtime.NumCPU() 28 fastrand.ShuffleSlice(keys) 29 ks := slice.Chunk(keys, size/cpus) 30 31 var wg sync.WaitGroup 32 for i := range ks { 33 wg.Add(1) 34 go func(i int) { 35 defer wg.Done() 36 37 for j := range ks[i] { 38 table.Insert(ks[i][j], ks[i][j]) 39 runtime.Gosched() 40 table.Insert(ks[i][j], ks[i][j]) 41 } 42 }(i) 43 } 44 wg.Wait() 45 46 fastrand.ShuffleSlice(keys) 47 for i := range keys { 48 v, ok := table.Lookup(keys[i]) 49 if !ok || v != keys[i] { 50 t.Fatalf("Expected %q, got %q", keys[i], v) 51 } 52 } 53 } 54 55 func TestTableDelete(t *testing.T) { 56 table := hashtable.New[string, string](1, hash.MemHashString64) 57 cpus := runtime.NumCPU() 58 fastrand.ShuffleSlice(keys) 59 ks := slice.Chunk(keys, size/cpus) 60 61 var wg sync.WaitGroup 62 for i := range ks { 63 wg.Add(1) 64 go func(i int) { 65 defer wg.Done() 66 67 for j := range ks[i] { 68 table.Insert(ks[i][j], ks[i][j]) 69 runtime.Gosched() 70 table.Delete(ks[i][j]) 71 } 72 }(i) 73 } 74 wg.Wait() 75 76 fastrand.ShuffleSlice(keys) 77 for i := range keys { 78 v, ok := table.Lookup(keys[i]) 79 if ok { 80 t.Fatalf("Table:%s Expected null, got %q", keys[i], v) 81 } 82 } 83 } 84 85 const size2 = 1 << 18 86 87 var keys2 []string = func() []string { 88 k := make([]string, size2) 89 for i := range k { 90 k[i] = strconv.Itoa(i * 10000) 91 } 92 return k 93 }() 94 95 func BenchmarkTableRead100(b *testing.B) { 96 table := hashtable.New[string, uint64](size2, hash.MemHashString64) 97 98 for i := range keys2 { 99 table.Insert(keys2[i], 0) 100 } 101 b.SetBytes(int64(size2 * 10)) 102 b.ResetTimer() 103 b.RunParallel(func(p *testing.PB) { 104 for p.Next() { 105 for i := range keys2 { 106 table.Lookup(keys2[i]) 107 table.Lookup(keys2[i]) 108 table.Lookup(keys2[i]) 109 table.Lookup(keys2[i]) 110 table.Lookup(keys2[i]) 111 table.Lookup(keys2[i]) 112 table.Lookup(keys2[i]) 113 table.Lookup(keys2[i]) 114 table.Lookup(keys2[i]) 115 table.Lookup(keys2[i]) 116 } 117 } 118 }) 119 } 120 121 func BenchmarkSyncMapRead100(b *testing.B) { 122 table := sync.Map{} 123 124 for i := range keys2 { 125 table.Store(keys2[i], 0) 126 } 127 b.SetBytes(int64(size2 * 10)) 128 b.ResetTimer() 129 b.RunParallel(func(p *testing.PB) { 130 for p.Next() { 131 for i := range keys2 { 132 table.Load(keys2[i]) 133 table.Load(keys2[i]) 134 table.Load(keys2[i]) 135 table.Load(keys2[i]) 136 table.Load(keys2[i]) 137 table.Load(keys2[i]) 138 table.Load(keys2[i]) 139 table.Load(keys2[i]) 140 table.Load(keys2[i]) 141 table.Load(keys2[i]) 142 } 143 } 144 }) 145 } 146 147 func BenchmarkTableRead90Write10(b *testing.B) { 148 table := hashtable.New[string, uint64](size2, hash.MemHashString64) 149 150 for i := range keys2 { 151 table.Insert(keys2[i], 0) 152 } 153 b.SetBytes(int64(size2 * 10)) 154 b.ResetTimer() 155 b.RunParallel(func(p *testing.PB) { 156 for p.Next() { 157 for i := range keys2 { 158 table.Lookup(keys2[i]) 159 table.Lookup(keys2[i]) 160 table.Lookup(keys2[i]) 161 table.Lookup(keys2[i]) 162 table.Lookup(keys2[i]) 163 table.Lookup(keys2[i]) 164 table.Lookup(keys2[i]) 165 table.Lookup(keys2[i]) 166 table.Lookup(keys2[i]) 167 table.Insert(keys2[i], 0) 168 } 169 } 170 }) 171 } 172 173 func BenchmarkSyncMapRead90Write10(b *testing.B) { 174 table := sync.Map{} 175 176 for i := range keys2 { 177 table.Store(keys2[i], 0) 178 } 179 b.SetBytes(int64(size2 * 10)) 180 b.ResetTimer() 181 b.RunParallel(func(p *testing.PB) { 182 for p.Next() { 183 for i := range keys2 { 184 table.Load(keys2[i]) 185 table.Load(keys2[i]) 186 table.Load(keys2[i]) 187 table.Load(keys2[i]) 188 table.Load(keys2[i]) 189 table.Load(keys2[i]) 190 table.Load(keys2[i]) 191 table.Load(keys2[i]) 192 table.Load(keys2[i]) 193 table.Store(keys2[i], 0) 194 } 195 } 196 }) 197 } 198 199 func BenchmarkTableRead70Write30(b *testing.B) { 200 table := hashtable.New[string, uint64](size2, hash.MemHashString64) 201 202 for i := range keys2 { 203 table.Insert(keys2[i], 0) 204 } 205 b.SetBytes(int64(size2 * 10)) 206 b.ResetTimer() 207 b.RunParallel(func(p *testing.PB) { 208 for p.Next() { 209 for i := range keys2 { 210 table.Lookup(keys2[i]) 211 table.Lookup(keys2[i]) 212 table.Lookup(keys2[i]) 213 table.Lookup(keys2[i]) 214 table.Lookup(keys2[i]) 215 table.Lookup(keys2[i]) 216 table.Lookup(keys2[i]) 217 table.Insert(keys2[i], 0) 218 table.Insert(keys2[i], 0) 219 table.Insert(keys2[i], 0) 220 } 221 } 222 }) 223 } 224 225 func BenchmarkSyncMapRead70Write30(b *testing.B) { 226 table := sync.Map{} 227 228 for i := range keys2 { 229 table.Store(keys2[i], 0) 230 } 231 b.SetBytes(int64(size2 * 10)) 232 b.ResetTimer() 233 b.RunParallel(func(p *testing.PB) { 234 for p.Next() { 235 for i := range keys2 { 236 table.Load(keys2[i]) 237 table.Load(keys2[i]) 238 table.Load(keys2[i]) 239 table.Load(keys2[i]) 240 table.Load(keys2[i]) 241 table.Load(keys2[i]) 242 table.Load(keys2[i]) 243 table.Store(keys2[i], 0) 244 table.Store(keys2[i], 0) 245 table.Store(keys2[i], 0) 246 } 247 } 248 }) 249 } 250 251 func BenchmarkTableRead50Write50(b *testing.B) { 252 table := hashtable.New[string, uint64](size2, hash.MemHashString64) 253 254 for i := range keys2 { 255 table.Insert(keys2[i], 0) 256 } 257 b.SetBytes(int64(size2 * 10)) 258 b.ResetTimer() 259 b.RunParallel(func(p *testing.PB) { 260 for p.Next() { 261 for i := range keys2 { 262 table.Lookup(keys2[i]) 263 table.Lookup(keys2[i]) 264 table.Lookup(keys2[i]) 265 table.Lookup(keys2[i]) 266 table.Lookup(keys2[i]) 267 table.Insert(keys2[i], 0) 268 table.Insert(keys2[i], 0) 269 table.Insert(keys2[i], 0) 270 table.Insert(keys2[i], 0) 271 table.Insert(keys2[i], 0) 272 } 273 } 274 }) 275 } 276 277 func BenchmarkSyncMapRead50Write50(b *testing.B) { 278 table := sync.Map{} 279 280 for i := range keys2 { 281 table.Store(keys2[i], 0) 282 } 283 b.SetBytes(int64(size2 * 10)) 284 b.ResetTimer() 285 b.RunParallel(func(p *testing.PB) { 286 for p.Next() { 287 for i := range keys2 { 288 table.Load(keys2[i]) 289 table.Load(keys2[i]) 290 table.Load(keys2[i]) 291 table.Load(keys2[i]) 292 table.Load(keys2[i]) 293 table.Store(keys2[i], 0) 294 table.Store(keys2[i], 0) 295 table.Store(keys2[i], 0) 296 table.Store(keys2[i], 0) 297 table.Store(keys2[i], 0) 298 } 299 } 300 }) 301 } 302 303 func BenchmarkTableRead30Write70(b *testing.B) { 304 table := hashtable.New[string, uint64](size2, hash.MemHashString64) 305 306 for i := range keys2 { 307 table.Insert(keys2[i], 0) 308 } 309 b.SetBytes(int64(size2 * 10)) 310 b.ResetTimer() 311 b.RunParallel(func(p *testing.PB) { 312 for p.Next() { 313 for i := range keys2 { 314 table.Lookup(keys2[i]) 315 table.Lookup(keys2[i]) 316 table.Lookup(keys2[i]) 317 table.Insert(keys2[i], 0) 318 table.Insert(keys2[i], 0) 319 table.Insert(keys2[i], 0) 320 table.Insert(keys2[i], 0) 321 table.Insert(keys2[i], 0) 322 table.Insert(keys2[i], 0) 323 table.Insert(keys2[i], 0) 324 } 325 } 326 }) 327 } 328 329 func BenchmarkSyncMapRead30Write70(b *testing.B) { 330 table := sync.Map{} 331 332 for i := range keys2 { 333 table.Store(keys2[i], 0) 334 } 335 b.SetBytes(int64(size2 * 10)) 336 b.ResetTimer() 337 b.RunParallel(func(p *testing.PB) { 338 for p.Next() { 339 for i := range keys2 { 340 table.Load(keys2[i]) 341 table.Load(keys2[i]) 342 table.Load(keys2[i]) 343 table.Store(keys2[i], 0) 344 table.Store(keys2[i], 0) 345 table.Store(keys2[i], 0) 346 table.Store(keys2[i], 0) 347 table.Store(keys2[i], 0) 348 table.Store(keys2[i], 0) 349 table.Store(keys2[i], 0) 350 } 351 } 352 }) 353 } 354 355 func BenchmarkTableRead10Write90(b *testing.B) { 356 table := hashtable.New[string, uint64](size2, hash.MemHashString64) 357 358 for i := range keys2 { 359 table.Insert(keys2[i], 0) 360 } 361 b.SetBytes(int64(size2 * 10)) 362 b.ResetTimer() 363 b.RunParallel(func(p *testing.PB) { 364 for p.Next() { 365 for i := range keys2 { 366 table.Lookup(keys2[i]) 367 table.Insert(keys2[i], 0) 368 table.Insert(keys2[i], 0) 369 table.Insert(keys2[i], 0) 370 table.Insert(keys2[i], 0) 371 table.Insert(keys2[i], 0) 372 table.Insert(keys2[i], 0) 373 table.Insert(keys2[i], 0) 374 table.Insert(keys2[i], 0) 375 table.Insert(keys2[i], 0) 376 } 377 } 378 }) 379 } 380 381 func BenchmarkSyncMapRead10Write90(b *testing.B) { 382 table := sync.Map{} 383 384 for i := range keys2 { 385 table.Store(keys2[i], 0) 386 } 387 b.SetBytes(int64(size2 * 10)) 388 b.ResetTimer() 389 b.RunParallel(func(p *testing.PB) { 390 for p.Next() { 391 for i := range keys2 { 392 table.Load(keys2[i]) 393 table.Store(keys2[i], 0) 394 table.Store(keys2[i], 0) 395 table.Store(keys2[i], 0) 396 table.Store(keys2[i], 0) 397 table.Store(keys2[i], 0) 398 table.Store(keys2[i], 0) 399 table.Store(keys2[i], 0) 400 table.Store(keys2[i], 0) 401 table.Store(keys2[i], 0) 402 } 403 } 404 }) 405 } 406 407 func BenchmarkTableWrite100(b *testing.B) { 408 table := hashtable.New[string, uint64](size2, hash.MemHashString64) 409 410 for i := range keys2 { 411 table.Insert(keys2[i], 0) 412 } 413 b.SetBytes(int64(size2 * 10)) 414 b.ResetTimer() 415 b.RunParallel(func(p *testing.PB) { 416 for p.Next() { 417 for i := range keys2 { 418 table.Insert(keys2[i], 0) 419 table.Insert(keys2[i], 0) 420 table.Insert(keys2[i], 0) 421 table.Insert(keys2[i], 0) 422 table.Insert(keys2[i], 0) 423 table.Insert(keys2[i], 0) 424 table.Insert(keys2[i], 0) 425 table.Insert(keys2[i], 0) 426 table.Insert(keys2[i], 0) 427 table.Insert(keys2[i], 0) 428 } 429 } 430 }) 431 } 432 433 func BenchmarkSyncMapWrite100(b *testing.B) { 434 table := sync.Map{} 435 436 for i := range keys2 { 437 table.Store(keys2[i], 0) 438 } 439 b.SetBytes(int64(size2 * 10)) 440 b.ResetTimer() 441 b.RunParallel(func(p *testing.PB) { 442 for p.Next() { 443 for i := range keys2 { 444 table.Store(keys2[i], 0) 445 table.Store(keys2[i], 0) 446 table.Store(keys2[i], 0) 447 table.Store(keys2[i], 0) 448 table.Store(keys2[i], 0) 449 table.Store(keys2[i], 0) 450 table.Store(keys2[i], 0) 451 table.Store(keys2[i], 0) 452 table.Store(keys2[i], 0) 453 table.Store(keys2[i], 0) 454 } 455 } 456 }) 457 }