83 lines
5.4 KiB
Markdown
83 lines
5.4 KiB
Markdown
# 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_one` calls 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:
|
|
|
|
```powershell
|
|
.\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`](baseline.csv).
|