|
| 1 | +# acdat benchmark notes |
| 2 | + |
| 3 | +The comprehensive real-corpus Go-versus-PostgreSQL report for the current |
| 4 | +Apple M5 Max test host is recorded in |
| 5 | +[`PERFORMANCE.md`](PERFORMANCE.md). |
| 6 | + |
| 7 | +## 2026-08-24: v0.2.0 benchmark-gated changes |
| 8 | + |
| 9 | +Environment: |
| 10 | + |
| 11 | +- Apple arm64, Apple clang 21.0.0 |
| 12 | +- `-O3 -DNDEBUG` |
| 13 | +- 16 MiB deterministic input per scan |
| 14 | +- three runs per cell; table values are medians |
| 15 | +- materialized format-major-1 runtime, matching the PostgreSQL cache path |
| 16 | + |
| 17 | +Command: |
| 18 | + |
| 19 | +```bash |
| 20 | +BENCH_REPEATS=3 BENCH_INPUT_MIB=16 make bench-matrix |
| 21 | +``` |
| 22 | + |
| 23 | +The comparison baseline was captured with the expanded benchmark immediately |
| 24 | +before the v0.2.0 core changes. The workload generator and compiler settings |
| 25 | +were otherwise identical. |
| 26 | + |
| 27 | +| 100K profile | v0.1 build | v0.2 build | v0.1 scan | v0.2 scan | |
| 28 | +|---|---:|---:|---:|---:| |
| 29 | +| ASCII miss | 0.280 s | 0.116 s | 59.97 MiB/s | 64.80 MiB/s | |
| 30 | +| Root-only miss | 0.278 s | 0.077 s | 449.67 MiB/s | 936.06 MiB/s | |
| 31 | +| ASCII hit-heavy | 0.278 s | 0.115 s | 226.42 MiB/s | 402.27 MiB/s | |
| 32 | +| UTF-8 byte miss | 19.269 s | 0.109 s | 485.55 MiB/s | 928.29 MiB/s | |
| 33 | + |
| 34 | +The UTF-8 build regression was caused by globally unique BASE values, a |
| 35 | +constraint needed by label-only Compact CHECK but not by acdat's parent-state |
| 36 | +Basic CHECK. Removing the constraint reduced the 100K UTF-8 base search to |
| 37 | +1,206,195 candidates, produced 1,303,302 slots for 1,303,082 states, and |
| 38 | +removed the `used_base` builder array. This simple change was sufficient; a |
| 39 | +free-list, XOR placement, and tail fallback were not added. |
| 40 | + |
| 41 | +The runtime output-chain preparation retains the format-major-1 artifact but |
| 42 | +releases the materialized `output_link` array. At 100K ASCII patterns, runtime |
| 43 | +bytes fell from 31,051,372 to 25,095,160 (19.2%). Artifact bytes also fell from |
| 44 | +31,051,452 to 30,367,716 because the relaxed BASE placement produced fewer |
| 45 | +vacant slots. A 1 KiB root transition table accounts for the small fixed |
| 46 | +runtime overhead. |
| 47 | + |
| 48 | +Two paper-derived experiments were rejected and removed: |
| 49 | + |
| 50 | +- LexDFS improved build time and the hit-heavy scan, but slowed the primary |
| 51 | + 100K ASCII-miss workload by about 60% and did not consistently improve the |
| 52 | + UTF-8 miss workload. LexBFS remains the only placement path. |
| 53 | +- Packed array-of-struct runtime states improved some large-machine cells but |
| 54 | + regressed a 1K machine by roughly 25%, slightly regressed the root-only cell, |
| 55 | + and added a second full materialization copy. The single SoA runtime remains. |
| 56 | + |
| 57 | +PostgreSQL 18.4, 100K generated `pattern-NNNNNNNN` rules, and one million |
| 58 | +short root-miss rows completed in a median 127.54 ms over three warm runs. The |
| 59 | +corresponding v0.1.0 note below recorded 275 ms. This is a PostgreSQL |
| 60 | +end-to-end measurement including function-call and executor overhead, not just |
| 61 | +the standalone scanner. |
| 62 | + |
| 63 | +These are local engineering results, not cross-platform release claims. Linux |
| 64 | +amd64/arm64, PostgreSQL short-row, parallel-worker, and package-lab results |
| 65 | +remain separate release gates. |
| 66 | + |
| 67 | +## 2026-08-22: byte256 ACDAT baseline |
| 68 | + |
| 69 | +Environment: |
| 70 | + |
| 71 | +- Apple arm64, Apple clang 21.0.0 |
| 72 | +- `-O3 -DNDEBUG` |
| 73 | +- Synthetic deterministic lowercase patterns, 16 bytes each |
| 74 | +- Deterministic lowercase random no-hit input |
| 75 | + |
| 76 | +Command: |
| 77 | + |
| 78 | +```bash |
| 79 | +PATTERNS=100000 PATTERN_BYTES=16 INPUT_MIB=16 make core-bench |
| 80 | +``` |
| 81 | + |
| 82 | +Results after the next-check-position density optimization: |
| 83 | + |
| 84 | +| Patterns | States | DAT slots | Occupancy | Artifact | Build | Scan | |
| 85 | +|---:|---:|---:|---:|---:|---:|---:| |
| 86 | +| 10,000 | 140,703 | 144,561 | 97.3% | 3.29 MB | 0.023 s | 88 MiB/s | |
| 87 | +| 100,000 | 1,318,279 | 1,356,597 | 97.2% | 31.13 MB | 0.271 s | 65 MiB/s | |
| 88 | + |
| 89 | +The pre-optimization 10K build took 5.5 seconds, and the 100K build did not |
| 90 | +finish within 150 seconds. The improvement comes from advancing the global |
| 91 | +base-search cursor when the scanned check-array window is at least 95% full, |
| 92 | +instead of repeatedly scanning isolated early holes. |
| 93 | + |
| 94 | +These are engineering baselines, not release claims. Follow-up benchmarks must |
| 95 | +include real Chinese/URL/IOC dictionaries, hit-heavy and overlap-heavy inputs, |
| 96 | +cold/warm TOAST, PostgreSQL per-row overhead, parallel workers, and a packed or |
| 97 | +sparse AC comparator. |
| 98 | + |
| 99 | +## 2026-08-22: PostgreSQL wrapper and TOAST cache |
| 100 | + |
| 101 | +PostgreSQL 18.4, local temporary table, 100K generated text patterns: |
| 102 | + |
| 103 | +- In-database aggregate compile + serialize: 86 ms |
| 104 | +- Artifact: 6.22 MB, 111,127 states, 111,205 slots |
| 105 | +- 1,000,000 short no-hit rows through one function expression: 275 ms |
| 106 | + |
| 107 | +The first implementation called `PG_GETARG_VARLENA_PP` before checking |
| 108 | +`fn_extra`; a 6.22 MB out-of-line value was therefore detoasted once per row and |
| 109 | +the same query ran for more than four minutes before cancellation. The fixed |
| 110 | +path compares the small on-disk TOAST pointer first and detoasts, validates, and |
| 111 | +materializes only when the build changes. This cache behavior is a release |
| 112 | +correctness/performance invariant and has dedicated regression/benchmark |
| 113 | +coverage. |
| 114 | + |
| 115 | +## 2026-08-22: historical Chinese dictionary |
| 116 | + |
| 117 | +The original repository's `dict.txt` contains 1,114 Chinese movie/music |
| 118 | +patterns. PostgreSQL 18.4 results: |
| 119 | + |
| 120 | +- Aggregate compile + serialize: 5.4 ms |
| 121 | +- 10,840 states / 11,357 DAT slots (95.4% occupancy) |
| 122 | +- Artifact: 283,074 bytes, including 11,182 replacement bytes |
| 123 | +- Maximum pattern: 40 UTF-8 bytes / 14 characters |
| 124 | +- 100,000 short hit-heavy rows through `acdat.contains`: 22.2 ms |
| 125 | + |
| 126 | +This confirms exact UTF-8 byte matching on the historical workload, but it is |
| 127 | +far smaller than the 100K target and does not replace a modern real-world CJK |
| 128 | +corpus benchmark. |
0 commit comments