github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/niterator/iterator_test.go (about) 1 package niterator 2 3 import ( 4 "testing" 5 6 "github.com/egonelbre/exp/niterator/basic" 7 "github.com/egonelbre/exp/niterator/instruct" 8 "github.com/egonelbre/exp/niterator/onearr" 9 "github.com/egonelbre/exp/niterator/onearrpremul" 10 "github.com/egonelbre/exp/niterator/onearrrev" 11 "github.com/egonelbre/exp/niterator/onearrrevadvance" 12 "github.com/egonelbre/exp/niterator/onearrrevspecialize" 13 "github.com/egonelbre/exp/niterator/onearrrevspecializeadvance" 14 "github.com/egonelbre/exp/niterator/ordone" 15 "github.com/egonelbre/exp/niterator/premul" 16 "github.com/egonelbre/exp/niterator/shape" 17 "github.com/egonelbre/exp/niterator/specialize" 18 "github.com/egonelbre/exp/niterator/unroll" 19 "github.com/egonelbre/exp/niterator/unrollinreverse" 20 "github.com/egonelbre/exp/niterator/unrollinreverseadvance" 21 "github.com/egonelbre/exp/niterator/unrollinreversebool" 22 "github.com/egonelbre/exp/niterator/unrollinreversehardcode" 23 "github.com/egonelbre/exp/niterator/unrollinreverseswitch" 24 "github.com/egonelbre/exp/niterator/unrollinverse" 25 "github.com/egonelbre/exp/niterator/unrollreverse" 26 ) 27 28 const skipUseless = true 29 30 type TestSize struct { 31 Name string 32 AP *shape.AP 33 } 34 35 var ( 36 indexOf100x = 5 37 testSizes = []TestSize{ 38 0: {"3x20x40x24", shape.New(3, 20, 40, 24)}, 39 1: {"24x20x40x3", shape.New(24, 20, 40, 3)}, 40 2: {"24x20x40x30", shape.New(24, 20, 40, 30)}, 41 3: {"5x50x100x150", shape.New(5, 50, 100, 150)}, 42 4: {"150x100x50x5", shape.New(150, 100, 50, 5)}, 43 5: {"100x100x100x100", shape.New(100, 100, 100, 100)}, 44 } 45 46 verifyIndex = make([][]int, len(testSizes)) 47 ) 48 49 func init() { 50 for api, testsize := range testSizes { 51 ap := testsize.AP 52 verify := make([]int, ap.TotalSize()) 53 54 it := basic.NewIterator(ap) 55 i := 0 56 for index, err := it.Next(); err == nil; index, err = it.Next() { 57 i++ 58 verify[index] = i 59 } 60 for _, v := range verify { 61 if v == 0 { 62 panic("invalid iterator") 63 } 64 } 65 66 verifyIndex[api] = verify 67 } 68 } 69 70 func testIterator(t *testing.T, newiterator func(ap *shape.AP) Iterator) { 71 t.Helper() 72 for api, testsize := range testSizes { 73 t.Run(testsize.Name, func(t *testing.T) { 74 verify := verifyIndex[api] 75 ap := testsize.AP 76 count := 0 77 i := 0 78 it := newiterator(ap) 79 for index, err := it.Next(); err == nil; index, err = it.Next() { 80 count++ 81 i++ 82 if verify[index] != i { 83 t.Fatalf("invalid at %d", index) 84 } 85 } 86 87 if count != ap.TotalSize() { 88 t.Fatalf("invalid count: got %d expected %d", count, ap.TotalSize()) 89 } 90 }) 91 } 92 } 93 94 func TestBasic(t *testing.T) { 95 testIterator(t, func(ap *shape.AP) Iterator { return basic.NewIterator(ap) }) 96 } 97 98 func BenchmarkBasic(b *testing.B) { 99 for api, testsize := range testSizes { 100 b.Run(testsize.Name, func(b *testing.B) { 101 verify := verifyIndex[api] 102 ap := testsize.AP 103 b.SetBytes(int64(ap.TotalSize())) 104 for i := 0; i < b.N; i++ { 105 it := basic.NewIterator(ap) 106 total := 0 107 for index, err := it.Next(); err == nil; index, err = it.Next() { 108 total += verify[index] * index 109 } 110 _ = total 111 } 112 }) 113 } 114 } 115 116 func TestInstruct(t *testing.T) { 117 if skipUseless { 118 t.Skip("skipping useless approach") 119 } 120 testIterator(t, func(ap *shape.AP) Iterator { return instruct.NewIterator(ap) }) 121 } 122 123 func BenchmarkInstruct(b *testing.B) { 124 if skipUseless { 125 b.Skip("skipping useless approach") 126 } 127 for api, testsize := range testSizes { 128 b.Run(testsize.Name, func(b *testing.B) { 129 verify := verifyIndex[api] 130 ap := testsize.AP 131 b.SetBytes(int64(ap.TotalSize())) 132 for i := 0; i < b.N; i++ { 133 it := instruct.NewIterator(ap) 134 total := 0 135 for index, err := it.Next(); err == nil; index, err = it.Next() { 136 total += verify[index] * index 137 } 138 _ = total 139 } 140 }) 141 } 142 } 143 144 func TestOrdone(t *testing.T) { 145 if skipUseless { 146 t.Skip("skipping useless approach") 147 } 148 testIterator(t, func(ap *shape.AP) Iterator { return ordone.NewIterator(ap) }) 149 } 150 151 func BenchmarkOrdone(b *testing.B) { 152 if skipUseless { 153 b.Skip("skipping useless approach") 154 } 155 for api, testsize := range testSizes { 156 b.Run(testsize.Name, func(b *testing.B) { 157 verify := verifyIndex[api] 158 ap := testsize.AP 159 b.SetBytes(int64(ap.TotalSize())) 160 for i := 0; i < b.N; i++ { 161 it := ordone.NewIterator(ap) 162 total := 0 163 for index, err := it.Next(); err == nil; index, err = it.Next() { 164 total += verify[index] * index 165 } 166 _ = total 167 } 168 }) 169 } 170 } 171 172 func TestPremul(t *testing.T) { 173 if skipUseless { 174 t.Skip("skipping useless approach") 175 } 176 testIterator(t, func(ap *shape.AP) Iterator { return premul.NewIterator(ap) }) 177 } 178 179 func BenchmarkPremul(b *testing.B) { 180 if skipUseless { 181 b.Skip("skipping useless approach") 182 } 183 for api, testsize := range testSizes { 184 b.Run(testsize.Name, func(b *testing.B) { 185 verify := verifyIndex[api] 186 ap := testsize.AP 187 b.SetBytes(int64(ap.TotalSize())) 188 for i := 0; i < b.N; i++ { 189 it := premul.NewIterator(ap) 190 total := 0 191 for index, err := it.Next(); err == nil; index, err = it.Next() { 192 total += verify[index] * index 193 } 194 _ = total 195 } 196 }) 197 } 198 } 199 200 func TestOnearr(t *testing.T) { 201 testIterator(t, func(ap *shape.AP) Iterator { return onearr.NewIterator(ap) }) 202 } 203 204 func BenchmarkOnearr(b *testing.B) { 205 for api, testsize := range testSizes { 206 b.Run(testsize.Name, func(b *testing.B) { 207 verify := verifyIndex[api] 208 ap := testsize.AP 209 b.SetBytes(int64(ap.TotalSize())) 210 for i := 0; i < b.N; i++ { 211 it := onearr.NewIterator(ap) 212 total := 0 213 for index, err := it.Next(); err == nil; index, err = it.Next() { 214 total += verify[index] * index 215 } 216 _ = total 217 } 218 }) 219 } 220 } 221 222 func TestOnearrRev(t *testing.T) { 223 testIterator(t, func(ap *shape.AP) Iterator { return onearrrev.NewIterator(ap) }) 224 } 225 226 func BenchmarkOnearrRev(b *testing.B) { 227 for api, testsize := range testSizes { 228 b.Run(testsize.Name, func(b *testing.B) { 229 verify := verifyIndex[api] 230 ap := testsize.AP 231 b.SetBytes(int64(ap.TotalSize())) 232 for i := 0; i < b.N; i++ { 233 it := onearrrev.NewIterator(ap) 234 total := 0 235 for index, err := it.Next(); err == nil; index, err = it.Next() { 236 total += verify[index] * index 237 } 238 _ = total 239 } 240 }) 241 } 242 } 243 244 func TestOnearrRevAdvance(t *testing.T) { 245 testIterator(t, func(ap *shape.AP) Iterator { return onearrrevadvance.NewIterator(ap) }) 246 } 247 248 func BenchmarkOnearrRevAdvance(b *testing.B) { 249 for api, testsize := range testSizes { 250 b.Run(testsize.Name, func(b *testing.B) { 251 verify := verifyIndex[api] 252 ap := testsize.AP 253 b.SetBytes(int64(ap.TotalSize())) 254 for i := 0; i < b.N; i++ { 255 it := onearrrevadvance.NewIterator(ap) 256 total := 0 257 for index, err := it.Next(); err == nil; index, err = it.Next() { 258 total += verify[index] * index 259 } 260 _ = total 261 } 262 }) 263 } 264 } 265 266 func TestOnearrRevSpecialize(t *testing.T) { 267 testIterator(t, func(ap *shape.AP) Iterator { return onearrrevspecialize.NewIterator(ap) }) 268 } 269 270 func BenchmarkOnearrRevSpecialize(b *testing.B) { 271 for api, testsize := range testSizes { 272 b.Run(testsize.Name, func(b *testing.B) { 273 verify := verifyIndex[api] 274 ap := testsize.AP 275 b.SetBytes(int64(ap.TotalSize())) 276 for i := 0; i < b.N; i++ { 277 it := onearrrevspecialize.NewIterator(ap) 278 total := 0 279 for index, err := it.Next(); err == nil; index, err = it.Next() { 280 total += verify[index] * index 281 } 282 _ = total 283 } 284 }) 285 } 286 } 287 288 func TestOnearrRevSpecializeAdvance(t *testing.T) { 289 testIterator(t, func(ap *shape.AP) Iterator { return onearrrevspecializeadvance.NewIterator(ap) }) 290 } 291 292 func BenchmarkOnearrRevSpecializeAdvance(b *testing.B) { 293 for api, testsize := range testSizes { 294 b.Run(testsize.Name, func(b *testing.B) { 295 verify := verifyIndex[api] 296 ap := testsize.AP 297 b.SetBytes(int64(ap.TotalSize())) 298 for i := 0; i < b.N; i++ { 299 it := onearrrevspecializeadvance.NewIterator(ap) 300 total := 0 301 for index, err := it.Next(); err == nil; index, err = it.Next() { 302 total += verify[index] * index 303 } 304 _ = total 305 } 306 }) 307 } 308 } 309 310 func TestOnearrPremul(t *testing.T) { 311 if skipUseless { 312 t.Skip("skipping useless approach") 313 } 314 testIterator(t, func(ap *shape.AP) Iterator { return onearrpremul.NewIterator(ap) }) 315 } 316 317 func BenchmarkOnearrPremul(b *testing.B) { 318 if skipUseless { 319 b.Skip("skipping useless approach") 320 } 321 for api, testsize := range testSizes { 322 b.Run(testsize.Name, func(b *testing.B) { 323 verify := verifyIndex[api] 324 ap := testsize.AP 325 b.SetBytes(int64(ap.TotalSize())) 326 for i := 0; i < b.N; i++ { 327 it := onearrpremul.NewIterator(ap) 328 total := 0 329 for index, err := it.Next(); err == nil; index, err = it.Next() { 330 total += verify[index] * index 331 } 332 _ = total 333 } 334 }) 335 } 336 } 337 338 func TestSpecialize(t *testing.T) { 339 testIterator(t, func(ap *shape.AP) Iterator { return specialize.NewIterator(ap) }) 340 } 341 342 func BenchmarkSpecialize(b *testing.B) { 343 for api, testsize := range testSizes { 344 b.Run(testsize.Name, func(b *testing.B) { 345 verify := verifyIndex[api] 346 ap := testsize.AP 347 b.SetBytes(int64(ap.TotalSize())) 348 for i := 0; i < b.N; i++ { 349 it := specialize.NewIterator(ap) 350 total := 0 351 for index, err := it.Next(); err == nil; index, err = it.Next() { 352 total += verify[index] * index 353 } 354 _ = total 355 } 356 }) 357 } 358 } 359 360 func TestUnroll(t *testing.T) { 361 testIterator(t, func(ap *shape.AP) Iterator { return unroll.NewIterator(ap) }) 362 } 363 364 func BenchmarkUnroll(b *testing.B) { 365 for api, testsize := range testSizes { 366 b.Run(testsize.Name, func(b *testing.B) { 367 verify := verifyIndex[api] 368 ap := testsize.AP 369 b.SetBytes(int64(ap.TotalSize())) 370 for i := 0; i < b.N; i++ { 371 it := unroll.NewIterator(ap) 372 total := 0 373 for index, err := it.Next(); err == nil; index, err = it.Next() { 374 total += verify[index] * index 375 } 376 _ = total 377 } 378 }) 379 } 380 } 381 382 func TestUnrollReverse(t *testing.T) { 383 testIterator(t, func(ap *shape.AP) Iterator { return unrollreverse.NewIterator(ap) }) 384 } 385 386 func BenchmarkUnrollReverse(b *testing.B) { 387 for api, testsize := range testSizes { 388 b.Run(testsize.Name, func(b *testing.B) { 389 verify := verifyIndex[api] 390 ap := testsize.AP 391 b.SetBytes(int64(ap.TotalSize())) 392 for i := 0; i < b.N; i++ { 393 it := unrollreverse.NewIterator(ap) 394 total := 0 395 for index, err := it.Next(); err == nil; index, err = it.Next() { 396 total += verify[index] * index 397 } 398 _ = total 399 } 400 }) 401 } 402 } 403 404 func TestUnrollInverse(t *testing.T) { 405 testIterator(t, func(ap *shape.AP) Iterator { return unrollinverse.NewIterator(ap) }) 406 } 407 408 func BenchmarkUnrollInverse(b *testing.B) { 409 for api, testsize := range testSizes { 410 b.Run(testsize.Name, func(b *testing.B) { 411 verify := verifyIndex[api] 412 ap := testsize.AP 413 b.SetBytes(int64(ap.TotalSize())) 414 for i := 0; i < b.N; i++ { 415 it := unrollinverse.NewIterator(ap) 416 total := 0 417 for index, err := it.Next(); err == nil; index, err = it.Next() { 418 total += verify[index] * index 419 } 420 _ = total 421 } 422 }) 423 } 424 } 425 426 func TestUnrollInReverse(t *testing.T) { 427 testIterator(t, func(ap *shape.AP) Iterator { return unrollinreverse.NewIterator(ap) }) 428 } 429 430 func BenchmarkUnrollInReverse(b *testing.B) { 431 for api, testsize := range testSizes { 432 b.Run(testsize.Name, func(b *testing.B) { 433 verify := verifyIndex[api] 434 ap := testsize.AP 435 b.SetBytes(int64(ap.TotalSize())) 436 for i := 0; i < b.N; i++ { 437 it := unrollinreverse.NewIterator(ap) 438 total := 0 439 for index, err := it.Next(); err == nil; index, err = it.Next() { 440 total += verify[index] * index 441 } 442 _ = total 443 } 444 }) 445 } 446 } 447 448 func TestUnrollInReverseAdvance(t *testing.T) { 449 testIterator(t, func(ap *shape.AP) Iterator { return unrollinreverseadvance.NewIterator(ap) }) 450 } 451 452 func BenchmarkUnrollInReverseAdvance(b *testing.B) { 453 for api, testsize := range testSizes { 454 b.Run(testsize.Name, func(b *testing.B) { 455 verify := verifyIndex[api] 456 ap := testsize.AP 457 b.SetBytes(int64(ap.TotalSize())) 458 for i := 0; i < b.N; i++ { 459 it := unrollinreverseadvance.NewIterator(ap) 460 total := 0 461 for index, err := it.Next(); err == nil; index, err = it.Next() { 462 total += verify[index] * index 463 } 464 _ = total 465 } 466 }) 467 } 468 } 469 470 func TestUnrollInReverseSwitch(t *testing.T) { 471 testIterator(t, func(ap *shape.AP) Iterator { return unrollinreverseswitch.NewIterator(ap) }) 472 } 473 474 func BenchmarkUnrollInReverseSwitch(b *testing.B) { 475 for api, testsize := range testSizes { 476 b.Run(testsize.Name, func(b *testing.B) { 477 verify := verifyIndex[api] 478 ap := testsize.AP 479 b.SetBytes(int64(ap.TotalSize())) 480 for i := 0; i < b.N; i++ { 481 it := unrollinreverseswitch.NewIterator(ap) 482 total := 0 483 for index, err := it.Next(); err == nil; index, err = it.Next() { 484 total += verify[index] * index 485 } 486 _ = total 487 } 488 }) 489 } 490 } 491 492 func BenchmarkUnrollInReverseBool(b *testing.B) { 493 for api, testsize := range testSizes { 494 b.Run(testsize.Name, func(b *testing.B) { 495 verify := verifyIndex[api] 496 ap := testsize.AP 497 b.SetBytes(int64(ap.TotalSize())) 498 for i := 0; i < b.N; i++ { 499 it := unrollinreversebool.NewIterator(ap) 500 total := 0 501 for index, done := it.Next(); !done; index, done = it.Next() { 502 total += verify[index] * index 503 } 504 _ = total 505 } 506 }) 507 } 508 } 509 510 // special 511 // func TestUnrollInReverseHardcode(t *testing.T) { 512 // testIterator(t, unrollinreversehardcode.NewIterator(shape.New(100, 100, 100, 100))) 513 // } 514 515 func BenchmarkUnrollInReverseHardcode(b *testing.B) { 516 b.Run("100x100x100x100", func(b *testing.B) { 517 verify := verifyIndex[indexOf100x] 518 ap := shape.New(100, 100, 100, 100) 519 b.SetBytes(int64(ap.TotalSize())) 520 for i := 0; i < b.N; i++ { 521 it := unrollinreversehardcode.NewIterator(ap) 522 total := 0 523 for index, err := it.Next(); err == nil; index, err = it.Next() { 524 total += verify[index] * index 525 } 526 _ = total 527 } 528 }) 529 }