5.4 KiB
Focused resize benchmark — 2026-08-13
This run replaces the retired benchmark matrix with one size sweep and one
fixed workload. Every candidate is AdaptiveSequence<uint32_t, true> and uses
the same flat hash index; only storage residency differs.
Workload per mixed trace:
- 97,000 random indexed reads (97%);
- 1,000
find_onecalls through the flat hash index (1%, 500 hit / 500 miss); - 1,000 random inserts (1%);
- 1,000 random erases (1%).
Each cell is the median of seven paired repeats. Candidate order is rotated per
repeat. Construction is outside the timer; automatic conversion on a resize
boundary is inside it. The per-operation columns are separate batched traces,
while mixed is the requested end-to-end workload.
Environment: AMD Ryzen 9 5900X (12 cores / 24 threads), Windows 11 Pro build
26200, MSVC 19.51.36248, x64 Release /O2 /MT, baseline ISA profile, no IPO/LTO.
Command:
.\out\bin\baseline\Release\uc_focused_bench.exe `
--operations 100000 --repeats 7 `
--output results\benchmarks\20260813-focused-resize\baseline.csv
Median throughput (operations/second)
| n | container | mixed mode | mixed leaf | mixed ops/s | indexed read ops/s | hash find ops/s | insert ops/s | erase ops/s |
|---|---|---|---|---|---|---|---|---|
| 256 | forced vector + hash | vector | 16 | 164,500,740 | 654,450,262 | 145,369,967 | 1,739,433 | 8,205,128 |
| 256 | forced tiered + hash | tiered | 17 | 41,291,601 | 54,182,922 | 81,479,671 | 2,459,420 | 5,203,252 |
| 256 | adaptive + hash | vector | 16 | 151,676,020 | 571,755,289 | 146,134,736 | 1,740,644 | 8,421,053 |
| 512 | forced vector + hash | vector | 23 | 103,412,616 | 657,030,223 | 129,584,035 | 1,358,880 | 5,014,691 |
| 512 | forced tiered + hash | tiered | 23 | 38,755,184 | 50,032,521 | 78,963,992 | 2,698,327 | 5,344,468 |
| 512 | adaptive + hash | vector | 23 | 98,328,417 | 575,373,993 | 129,098,890 | 1,300,221 | 5,256,674 |
| 1,024 | forced vector + hash | vector | 32 | 58,816,610 | 662,251,656 | 110,411,836 | 931,619 | 2,801,120 |
| 1,024 | forced tiered + hash | tiered | 33 | 35,664,610 | 46,172,315 | 71,118,697 | 3,144,654 | 4,748,338 |
| 1,024 | adaptive + hash | vector | 32 | 56,631,555 | 584,112,150 | 109,673,174 | 911,743 | 2,893,519 |
| 2,048 | forced vector + hash | vector | 46 | 31,979,533 | 654,878,847 | 81,426,594 | 570,125 | 973,615 |
| 2,048 | forced tiered + hash | tiered | 46 | 32,177,103 | 43,327,556 | 59,157,596 | 2,581,311 | 3,880,481 |
| 2,048 | adaptive + hash | vector | 46 | 31,330,284 | 580,383,053 | 81,406,708 | 565,835 | 995,619 |
| 4,096 | forced vector + hash | vector | 64 | 17,199,862 | 661,813,369 | 77,297,673 | 313,342 | 421,248 |
| 4,096 | forced tiered + hash | tiered | 65 | 32,526,672 | 45,460,745 | 55,303,617 | 1,793,079 | 3,138,732 |
| 4,096 | adaptive + hash | vector → tiered | 65 | 32,639,206 | 581,395,349 | 76,710,647 | 1,822,822 | 422,048 |
| 8,192 | forced vector + hash | vector | 91 | 8,791,518 | 657,894,737 | 72,385,089 | 164,395 | 198,736 |
| 8,192 | forced tiered + hash | tiered | 91 | 28,479,481 | 42,929,510 | 51,116,904 | 1,317,003 | 2,276,867 |
| 8,192 | adaptive + hash | tiered | 91 | 28,603,301 | 40,546,568 | 50,296,751 | 1,348,618 | 2,704,896 |
| 16,384 | forced vector + hash | vector | 128 | 4,489,580 | 649,350,649 | 79,478,620 | 86,972 | 96,230 |
| 16,384 | forced tiered + hash | tiered | 129 | 23,255,814 | 40,364,899 | 51,284,681 | 935,629 | 1,709,694 |
| 16,384 | adaptive + hash | tiered | 129 | 22,955,260 | 38,213,153 | 50,658,561 | 836,400 | 2,076,843 |
| 32,768 | forced vector + hash | vector | 182 | 2,246,076 | 610,873,549 | 79,687,625 | 43,018 | 47,784 |
| 32,768 | forced tiered + hash | tiered | 182 | 18,402,989 | 37,572,797 | 50,266,412 | 571,004 | 1,245,640 |
| 32,768 | adaptive + hash | tiered | 182 | 17,943,013 | 35,944,071 | 49,058,085 | 514,165 | 1,548,227 |
| 65,536 | forced vector + hash | vector | 256 | 1,089,099 | 490,436,488 | 63,678,044 | 21,507 | 22,895 |
| 65,536 | forced tiered + hash | tiered | 257 | 12,614,158 | 32,799,790 | 44,620,945 | 315,139 | 910,167 |
| 65,536 | adaptive + hash | tiered | 257 | 12,777,430 | 30,628,809 | 42,513,392 | 295,255 | 1,116,819 |
Crossover
At n=2,048, forced tiered had only a 0.618% median advantage and won four of
seven paired repeats (forced vector won three), so this boundary is treated as
noise rather than a stable crossover. At n=4,096, forced tiered won all seven
paired repeats and its median throughput was 1.8911x that of forced vector.
The adaptive row includes the one-time vector → tiered conversion and still
reached 32.64M mixed ops/s, essentially matching already-tiered storage.
Therefore the calibrated resize-boundary cutoff is 4,096 elements, the
first decisive and stable size in this sweep.
At exactly 4,096 elements an adaptive container is still vector. The next
insert changes logical capacity from 4,096 to 8,192 and performs the conversion;
the final leaf is ceil(sqrt(4097)) = 65. In the separate read/find/erase
batches no growth occurs, so those adaptive 4,096 measurements remain vector;
the insert batch and mixed trace include the conversion.
All 189 raw rows have the required operation counts, and checksums match across
the three candidates for every (n, repeat) pair. The CSV also records the
mode and leaf used by each separate read/find/insert/erase batch. Raw data is in
baseline.csv.