github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/pot/pot_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:48</date> 10 //</624342677000818688> 11 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 // 25 // 26 // 27 package pot 28 29 import ( 30 "errors" 31 "fmt" 32 "math/rand" 33 "runtime" 34 "sync" 35 "testing" 36 "time" 37 38 "github.com/ethereum/go-ethereum/swarm/log" 39 ) 40 41 const ( 42 maxEachNeighbourTests = 420 43 maxEachNeighbour = 420 44 maxSwap = 420 45 maxSwapTests = 420 46 ) 47 48 // 49 // 50 // 51 52 type testAddr struct { 53 a []byte 54 i int 55 } 56 57 func newTestAddr(s string, i int) *testAddr { 58 return &testAddr{NewAddressFromString(s), i} 59 } 60 61 func (a *testAddr) Address() []byte { 62 return a.a 63 } 64 65 func (a *testAddr) String() string { 66 return Label(a.a) 67 } 68 69 func randomTestAddr(n int, i int) *testAddr { 70 v := RandomAddress().Bin()[:n] 71 return newTestAddr(v, i) 72 } 73 74 func randomtestAddr(n int, i int) *testAddr { 75 v := RandomAddress().Bin()[:n] 76 return newTestAddr(v, i) 77 } 78 79 func indexes(t *Pot) (i []int, po []int) { 80 t.Each(func(v Val, p int) bool { 81 a := v.(*testAddr) 82 i = append(i, a.i) 83 po = append(po, p) 84 return true 85 }) 86 return i, po 87 } 88 89 func testAdd(t *Pot, pof Pof, j int, values ...string) (_ *Pot, n int, f bool) { 90 for i, val := range values { 91 t, n, f = Add(t, newTestAddr(val, i+j), pof) 92 } 93 return t, n, f 94 } 95 96 func TestPotAdd(t *testing.T) { 97 pof := DefaultPof(8) 98 n := NewPot(newTestAddr("00111100", 0), 0) 99 // 100 exp := "00111100" 101 got := Label(n.Pin())[:8] 102 if got != exp { 103 t.Fatalf("incorrect pinned value. Expected %v, got %v", exp, got) 104 } 105 // 106 goti := n.Size() 107 expi := 1 108 if goti != expi { 109 t.Fatalf("incorrect number of elements in Pot. Expected %v, got %v", expi, goti) 110 } 111 112 n, _, _ = testAdd(n, pof, 1, "01111100", "00111100", "01111100", "00011100") 113 // 114 goti = n.Size() 115 expi = 3 116 if goti != expi { 117 t.Fatalf("incorrect number of elements in Pot. Expected %v, got %v", expi, goti) 118 } 119 inds, po := indexes(n) 120 got = fmt.Sprintf("%v", inds) 121 exp = "[3 4 2]" 122 if got != exp { 123 t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got) 124 } 125 got = fmt.Sprintf("%v", po) 126 exp = "[1 2 0]" 127 if got != exp { 128 t.Fatalf("incorrect po-s in iteration over Pot. Expected %v, got %v", exp, got) 129 } 130 } 131 132 func TestPotRemove(t *testing.T) { 133 pof := DefaultPof(8) 134 n := NewPot(newTestAddr("00111100", 0), 0) 135 n, _, _ = Remove(n, newTestAddr("00111100", 0), pof) 136 exp := "<nil>" 137 got := Label(n.Pin()) 138 if got != exp { 139 t.Fatalf("incorrect pinned value. Expected %v, got %v", exp, got) 140 } 141 n, _, _ = testAdd(n, pof, 1, "00000000", "01111100", "00111100", "00011100") 142 n, _, _ = Remove(n, newTestAddr("00111100", 0), pof) 143 goti := n.Size() 144 expi := 3 145 if goti != expi { 146 t.Fatalf("incorrect number of elements in Pot. Expected %v, got %v", expi, goti) 147 } 148 inds, po := indexes(n) 149 got = fmt.Sprintf("%v", inds) 150 exp = "[2 4 0]" 151 if got != exp { 152 t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got) 153 } 154 got = fmt.Sprintf("%v", po) 155 exp = "[1 3 0]" 156 if got != exp { 157 t.Fatalf("incorrect po-s in iteration over Pot. Expected %v, got %v", exp, got) 158 } 159 // 160 n, _, _ = Remove(n, newTestAddr("00111100", 0), pof) 161 inds, _ = indexes(n) 162 got = fmt.Sprintf("%v", inds) 163 exp = "[2 4]" 164 if got != exp { 165 t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got) 166 } 167 168 } 169 170 func TestPotSwap(t *testing.T) { 171 for i := 0; i < maxSwapTests; i++ { 172 alen := maxkeylen 173 pof := DefaultPof(alen) 174 max := rand.Intn(maxSwap) 175 176 n := NewPot(nil, 0) 177 var m []*testAddr 178 var found bool 179 for j := 0; j < 2*max; { 180 v := randomtestAddr(alen, j) 181 n, _, found = Add(n, v, pof) 182 if !found { 183 m = append(m, v) 184 j++ 185 } 186 } 187 k := make(map[string]*testAddr) 188 for j := 0; j < max; { 189 v := randomtestAddr(alen, 1) 190 _, found := k[Label(v)] 191 if !found { 192 k[Label(v)] = v 193 j++ 194 } 195 } 196 for _, v := range k { 197 m = append(m, v) 198 } 199 f := func(v Val) Val { 200 tv := v.(*testAddr) 201 if tv.i < max { 202 return nil 203 } 204 tv.i = 0 205 return v 206 } 207 for _, val := range m { 208 n, _, _, _ = Swap(n, val, pof, func(v Val) Val { 209 if v == nil { 210 return val 211 } 212 return f(v) 213 }) 214 } 215 sum := 0 216 n.Each(func(v Val, i int) bool { 217 if v == nil { 218 return true 219 } 220 sum++ 221 tv := v.(*testAddr) 222 if tv.i > 1 { 223 t.Fatalf("item value incorrect, expected 0, got %v", tv.i) 224 } 225 return true 226 }) 227 if sum != 2*max { 228 t.Fatalf("incorrect number of elements. expected %v, got %v", 2*max, sum) 229 } 230 if sum != n.Size() { 231 t.Fatalf("incorrect size. expected %v, got %v", sum, n.Size()) 232 } 233 } 234 } 235 236 func checkPo(val Val, pof Pof) func(Val, int) error { 237 return func(v Val, po int) error { 238 // 239 exp, _ := pof(val, v, 0) 240 if po != exp { 241 return fmt.Errorf("incorrect prox order for item %v in neighbour iteration for %v. Expected %v, got %v", v, val, exp, po) 242 } 243 return nil 244 } 245 } 246 247 func checkOrder(val Val) func(Val, int) error { 248 po := maxkeylen 249 return func(v Val, p int) error { 250 if po < p { 251 return fmt.Errorf("incorrect order for item %v in neighbour iteration for %v. PO %v > %v (previous max)", v, val, p, po) 252 } 253 po = p 254 return nil 255 } 256 } 257 258 func checkValues(m map[string]bool, val Val) func(Val, int) error { 259 return func(v Val, po int) error { 260 duplicate, ok := m[Label(v)] 261 if !ok { 262 return fmt.Errorf("alien value %v", v) 263 } 264 if duplicate { 265 return fmt.Errorf("duplicate value returned: %v", v) 266 } 267 m[Label(v)] = true 268 return nil 269 } 270 } 271 272 var errNoCount = errors.New("not count") 273 274 func testPotEachNeighbour(n *Pot, pof Pof, val Val, expCount int, fs ...func(Val, int) error) error { 275 var err error 276 var count int 277 n.EachNeighbour(val, pof, func(v Val, po int) bool { 278 for _, f := range fs { 279 err = f(v, po) 280 if err != nil { 281 return err.Error() == errNoCount.Error() 282 } 283 } 284 count++ 285 return count != expCount 286 }) 287 if err == nil && count < expCount { 288 return fmt.Errorf("not enough neighbours returned, expected %v, got %v", expCount, count) 289 } 290 return err 291 } 292 293 const ( 294 mergeTestCount = 5 295 mergeTestChoose = 5 296 ) 297 298 func TestPotMergeCommon(t *testing.T) { 299 vs := make([]*testAddr, mergeTestCount) 300 for i := 0; i < maxEachNeighbourTests; i++ { 301 alen := maxkeylen 302 pof := DefaultPof(alen) 303 304 for j := 0; j < len(vs); j++ { 305 vs[j] = randomtestAddr(alen, j) 306 } 307 max0 := rand.Intn(mergeTestChoose) + 1 308 max1 := rand.Intn(mergeTestChoose) + 1 309 n0 := NewPot(nil, 0) 310 n1 := NewPot(nil, 0) 311 log.Trace(fmt.Sprintf("round %v: %v - %v", i, max0, max1)) 312 m := make(map[string]bool) 313 var found bool 314 for j := 0; j < max0; { 315 r := rand.Intn(max0) 316 v := vs[r] 317 n0, _, found = Add(n0, v, pof) 318 if !found { 319 m[Label(v)] = false 320 j++ 321 } 322 } 323 expAdded := 0 324 325 for j := 0; j < max1; { 326 r := rand.Intn(max1) 327 v := vs[r] 328 n1, _, found = Add(n1, v, pof) 329 if !found { 330 j++ 331 } 332 _, found = m[Label(v)] 333 if !found { 334 expAdded++ 335 m[Label(v)] = false 336 } 337 } 338 if i < 6 { 339 continue 340 } 341 expSize := len(m) 342 log.Trace(fmt.Sprintf("%v-0: pin: %v, size: %v", i, n0.Pin(), max0)) 343 log.Trace(fmt.Sprintf("%v-1: pin: %v, size: %v", i, n1.Pin(), max1)) 344 log.Trace(fmt.Sprintf("%v: merged tree size: %v, newly added: %v", i, expSize, expAdded)) 345 n, common := Union(n0, n1, pof) 346 added := n1.Size() - common 347 size := n.Size() 348 349 if expSize != size { 350 t.Fatalf("%v: incorrect number of elements in merged pot, expected %v, got %v\n%v", i, expSize, size, n) 351 } 352 if expAdded != added { 353 t.Fatalf("%v: incorrect number of added elements in merged pot, expected %v, got %v", i, expAdded, added) 354 } 355 if !checkDuplicates(n) { 356 t.Fatalf("%v: merged pot contains duplicates: \n%v", i, n) 357 } 358 for k := range m { 359 _, _, found = Add(n, newTestAddr(k, 0), pof) 360 if !found { 361 t.Fatalf("%v: merged pot (size:%v, added: %v) missing element %v", i, size, added, k) 362 } 363 } 364 } 365 } 366 367 func TestPotMergeScale(t *testing.T) { 368 for i := 0; i < maxEachNeighbourTests; i++ { 369 alen := maxkeylen 370 pof := DefaultPof(alen) 371 max0 := rand.Intn(maxEachNeighbour) + 1 372 max1 := rand.Intn(maxEachNeighbour) + 1 373 n0 := NewPot(nil, 0) 374 n1 := NewPot(nil, 0) 375 log.Trace(fmt.Sprintf("round %v: %v - %v", i, max0, max1)) 376 m := make(map[string]bool) 377 var found bool 378 for j := 0; j < max0; { 379 v := randomtestAddr(alen, j) 380 n0, _, found = Add(n0, v, pof) 381 if !found { 382 m[Label(v)] = false 383 j++ 384 } 385 } 386 expAdded := 0 387 388 for j := 0; j < max1; { 389 v := randomtestAddr(alen, j) 390 n1, _, found = Add(n1, v, pof) 391 if !found { 392 j++ 393 } 394 _, found = m[Label(v)] 395 if !found { 396 expAdded++ 397 m[Label(v)] = false 398 } 399 } 400 if i < 6 { 401 continue 402 } 403 expSize := len(m) 404 log.Trace(fmt.Sprintf("%v-0: pin: %v, size: %v", i, n0.Pin(), max0)) 405 log.Trace(fmt.Sprintf("%v-1: pin: %v, size: %v", i, n1.Pin(), max1)) 406 log.Trace(fmt.Sprintf("%v: merged tree size: %v, newly added: %v", i, expSize, expAdded)) 407 n, common := Union(n0, n1, pof) 408 added := n1.Size() - common 409 size := n.Size() 410 411 if expSize != size { 412 t.Fatalf("%v: incorrect number of elements in merged pot, expected %v, got %v", i, expSize, size) 413 } 414 if expAdded != added { 415 t.Fatalf("%v: incorrect number of added elements in merged pot, expected %v, got %v", i, expAdded, added) 416 } 417 if !checkDuplicates(n) { 418 t.Fatalf("%v: merged pot contains duplicates", i) 419 } 420 for k := range m { 421 _, _, found = Add(n, newTestAddr(k, 0), pof) 422 if !found { 423 t.Fatalf("%v: merged pot (size:%v, added: %v) missing element %v", i, size, added, k) 424 } 425 } 426 } 427 } 428 429 func checkDuplicates(t *Pot) bool { 430 po := -1 431 for _, c := range t.bins { 432 if c == nil { 433 return false 434 } 435 if c.po <= po || !checkDuplicates(c) { 436 return false 437 } 438 po = c.po 439 } 440 return true 441 } 442 443 func TestPotEachNeighbourSync(t *testing.T) { 444 for i := 0; i < maxEachNeighbourTests; i++ { 445 alen := maxkeylen 446 pof := DefaultPof(maxkeylen) 447 max := rand.Intn(maxEachNeighbour/2) + maxEachNeighbour/2 448 pin := randomTestAddr(alen, 0) 449 n := NewPot(pin, 0) 450 m := make(map[string]bool) 451 m[Label(pin)] = false 452 for j := 1; j <= max; j++ { 453 v := randomTestAddr(alen, j) 454 n, _, _ = Add(n, v, pof) 455 m[Label(v)] = false 456 } 457 458 size := n.Size() 459 if size < 2 { 460 continue 461 } 462 count := rand.Intn(size/2) + size/2 463 val := randomTestAddr(alen, max+1) 464 log.Trace(fmt.Sprintf("%v: pin: %v, size: %v, val: %v, count: %v", i, n.Pin(), size, val, count)) 465 err := testPotEachNeighbour(n, pof, val, count, checkPo(val, pof), checkOrder(val), checkValues(m, val)) 466 if err != nil { 467 t.Fatal(err) 468 } 469 minPoFound := alen 470 maxPoNotFound := 0 471 for k, found := range m { 472 po, _ := pof(val, newTestAddr(k, 0), 0) 473 if found { 474 if po < minPoFound { 475 minPoFound = po 476 } 477 } else { 478 if po > maxPoNotFound { 479 maxPoNotFound = po 480 } 481 } 482 } 483 if minPoFound < maxPoNotFound { 484 t.Fatalf("incorrect neighbours returned: found one with PO %v < there was one not found with PO %v", minPoFound, maxPoNotFound) 485 } 486 } 487 } 488 489 func TestPotEachNeighbourAsync(t *testing.T) { 490 for i := 0; i < maxEachNeighbourTests; i++ { 491 max := rand.Intn(maxEachNeighbour/2) + maxEachNeighbour/2 492 alen := maxkeylen 493 pof := DefaultPof(alen) 494 n := NewPot(randomTestAddr(alen, 0), 0) 495 size := 1 496 var found bool 497 for j := 1; j <= max; j++ { 498 v := randomTestAddr(alen, j) 499 n, _, found = Add(n, v, pof) 500 if !found { 501 size++ 502 } 503 } 504 if size != n.Size() { 505 t.Fatal(n) 506 } 507 if size < 2 { 508 continue 509 } 510 count := rand.Intn(size/2) + size/2 511 val := randomTestAddr(alen, max+1) 512 513 mu := sync.Mutex{} 514 m := make(map[string]bool) 515 maxPos := rand.Intn(alen) 516 log.Trace(fmt.Sprintf("%v: pin: %v, size: %v, val: %v, count: %v, maxPos: %v", i, n.Pin(), size, val, count, maxPos)) 517 msize := 0 518 remember := func(v Val, po int) error { 519 if po > maxPos { 520 return errNoCount 521 } 522 m[Label(v)] = true 523 msize++ 524 return nil 525 } 526 if i == 0 { 527 continue 528 } 529 testPotEachNeighbour(n, pof, val, count, remember) 530 d := 0 531 forget := func(v Val, po int) { 532 mu.Lock() 533 defer mu.Unlock() 534 d++ 535 delete(m, Label(v)) 536 } 537 538 n.EachNeighbourAsync(val, pof, count, maxPos, forget, true) 539 if d != msize { 540 t.Fatalf("incorrect number of neighbour calls in async iterator. expected %v, got %v", msize, d) 541 } 542 if len(m) != 0 { 543 t.Fatalf("incorrect neighbour calls in async iterator. %v items missed:\n%v", len(m), n) 544 } 545 } 546 } 547 548 func benchmarkEachNeighbourSync(t *testing.B, max, count int, d time.Duration) { 549 t.ReportAllocs() 550 alen := maxkeylen 551 pof := DefaultPof(alen) 552 pin := randomTestAddr(alen, 0) 553 n := NewPot(pin, 0) 554 var found bool 555 for j := 1; j <= max; { 556 v := randomTestAddr(alen, j) 557 n, _, found = Add(n, v, pof) 558 if !found { 559 j++ 560 } 561 } 562 t.ResetTimer() 563 for i := 0; i < t.N; i++ { 564 val := randomTestAddr(alen, max+1) 565 m := 0 566 n.EachNeighbour(val, pof, func(v Val, po int) bool { 567 time.Sleep(d) 568 m++ 569 return m != count 570 }) 571 } 572 t.StopTimer() 573 stats := new(runtime.MemStats) 574 runtime.ReadMemStats(stats) 575 } 576 577 func benchmarkEachNeighbourAsync(t *testing.B, max, count int, d time.Duration) { 578 t.ReportAllocs() 579 alen := maxkeylen 580 pof := DefaultPof(alen) 581 pin := randomTestAddr(alen, 0) 582 n := NewPot(pin, 0) 583 var found bool 584 for j := 1; j <= max; { 585 v := randomTestAddr(alen, j) 586 n, _, found = Add(n, v, pof) 587 if !found { 588 j++ 589 } 590 } 591 t.ResetTimer() 592 for i := 0; i < t.N; i++ { 593 val := randomTestAddr(alen, max+1) 594 n.EachNeighbourAsync(val, pof, count, alen, func(v Val, po int) { 595 time.Sleep(d) 596 }, true) 597 } 598 t.StopTimer() 599 stats := new(runtime.MemStats) 600 runtime.ReadMemStats(stats) 601 } 602 603 func BenchmarkEachNeighbourSync_3_1_0(t *testing.B) { 604 benchmarkEachNeighbourSync(t, 1000, 10, 1*time.Microsecond) 605 } 606 func BenchmarkEachNeighboursAsync_3_1_0(t *testing.B) { 607 benchmarkEachNeighbourAsync(t, 1000, 10, 1*time.Microsecond) 608 } 609 func BenchmarkEachNeighbourSync_3_2_0(t *testing.B) { 610 benchmarkEachNeighbourSync(t, 1000, 100, 1*time.Microsecond) 611 } 612 func BenchmarkEachNeighboursAsync_3_2_0(t *testing.B) { 613 benchmarkEachNeighbourAsync(t, 1000, 100, 1*time.Microsecond) 614 } 615 func BenchmarkEachNeighbourSync_3_3_0(t *testing.B) { 616 benchmarkEachNeighbourSync(t, 1000, 1000, 1*time.Microsecond) 617 } 618 func BenchmarkEachNeighboursAsync_3_3_0(t *testing.B) { 619 benchmarkEachNeighbourAsync(t, 1000, 1000, 1*time.Microsecond) 620 } 621 622 func BenchmarkEachNeighbourSync_3_1_1(t *testing.B) { 623 benchmarkEachNeighbourSync(t, 1000, 10, 2*time.Microsecond) 624 } 625 func BenchmarkEachNeighboursAsync_3_1_1(t *testing.B) { 626 benchmarkEachNeighbourAsync(t, 1000, 10, 2*time.Microsecond) 627 } 628 func BenchmarkEachNeighbourSync_3_2_1(t *testing.B) { 629 benchmarkEachNeighbourSync(t, 1000, 100, 2*time.Microsecond) 630 } 631 func BenchmarkEachNeighboursAsync_3_2_1(t *testing.B) { 632 benchmarkEachNeighbourAsync(t, 1000, 100, 2*time.Microsecond) 633 } 634 func BenchmarkEachNeighbourSync_3_3_1(t *testing.B) { 635 benchmarkEachNeighbourSync(t, 1000, 1000, 2*time.Microsecond) 636 } 637 func BenchmarkEachNeighboursAsync_3_3_1(t *testing.B) { 638 benchmarkEachNeighbourAsync(t, 1000, 1000, 2*time.Microsecond) 639 } 640 641 func BenchmarkEachNeighbourSync_3_1_2(t *testing.B) { 642 benchmarkEachNeighbourSync(t, 1000, 10, 4*time.Microsecond) 643 } 644 func BenchmarkEachNeighboursAsync_3_1_2(t *testing.B) { 645 benchmarkEachNeighbourAsync(t, 1000, 10, 4*time.Microsecond) 646 } 647 func BenchmarkEachNeighbourSync_3_2_2(t *testing.B) { 648 benchmarkEachNeighbourSync(t, 1000, 100, 4*time.Microsecond) 649 } 650 func BenchmarkEachNeighboursAsync_3_2_2(t *testing.B) { 651 benchmarkEachNeighbourAsync(t, 1000, 100, 4*time.Microsecond) 652 } 653 func BenchmarkEachNeighbourSync_3_3_2(t *testing.B) { 654 benchmarkEachNeighbourSync(t, 1000, 1000, 4*time.Microsecond) 655 } 656 func BenchmarkEachNeighboursAsync_3_3_2(t *testing.B) { 657 benchmarkEachNeighbourAsync(t, 1000, 1000, 4*time.Microsecond) 658 } 659 660 func BenchmarkEachNeighbourSync_3_1_3(t *testing.B) { 661 benchmarkEachNeighbourSync(t, 1000, 10, 8*time.Microsecond) 662 } 663 func BenchmarkEachNeighboursAsync_3_1_3(t *testing.B) { 664 benchmarkEachNeighbourAsync(t, 1000, 10, 8*time.Microsecond) 665 } 666 func BenchmarkEachNeighbourSync_3_2_3(t *testing.B) { 667 benchmarkEachNeighbourSync(t, 1000, 100, 8*time.Microsecond) 668 } 669 func BenchmarkEachNeighboursAsync_3_2_3(t *testing.B) { 670 benchmarkEachNeighbourAsync(t, 1000, 100, 8*time.Microsecond) 671 } 672 func BenchmarkEachNeighbourSync_3_3_3(t *testing.B) { 673 benchmarkEachNeighbourSync(t, 1000, 1000, 8*time.Microsecond) 674 } 675 func BenchmarkEachNeighboursAsync_3_3_3(t *testing.B) { 676 benchmarkEachNeighbourAsync(t, 1000, 1000, 8*time.Microsecond) 677 } 678 679 func BenchmarkEachNeighbourSync_3_1_4(t *testing.B) { 680 benchmarkEachNeighbourSync(t, 1000, 10, 16*time.Microsecond) 681 } 682 func BenchmarkEachNeighboursAsync_3_1_4(t *testing.B) { 683 benchmarkEachNeighbourAsync(t, 1000, 10, 16*time.Microsecond) 684 } 685 func BenchmarkEachNeighbourSync_3_2_4(t *testing.B) { 686 benchmarkEachNeighbourSync(t, 1000, 100, 16*time.Microsecond) 687 } 688 func BenchmarkEachNeighboursAsync_3_2_4(t *testing.B) { 689 benchmarkEachNeighbourAsync(t, 1000, 100, 16*time.Microsecond) 690 } 691 func BenchmarkEachNeighbourSync_3_3_4(t *testing.B) { 692 benchmarkEachNeighbourSync(t, 1000, 1000, 16*time.Microsecond) 693 } 694 func BenchmarkEachNeighboursAsync_3_3_4(t *testing.B) { 695 benchmarkEachNeighbourAsync(t, 1000, 1000, 16*time.Microsecond) 696 } 697