Skip to content

bench: refresh competitive table from single fresh-process run - #55

Merged
stffns merged 2 commits into
mainfrom
bench/clean-rerun-v010
Apr 20, 2026
Merged

stffns merged 2 commits into
mainfrom
bench/clean-rerun-v010

Conversation

@stffns

@stffns stffns commented Apr 20, 2026

Copy link
Copy Markdown
Owner

Summary

Jay flagged a 56% p50 delta on SnapIndex 4-bit between two earlier
measurements (4244 us vs 2727 us on the same config). Too big for
query noise. Re-ran the full `bench_competitive.py` start-to-finish
in one fresh Python session on main (post v0.10.0 merge, commit
`8a28af1`) to confirm the published table.

Findings

Run-to-run delta vs the previously published numbers:

Backend published p50 fresh p50 delta
sqlite-vec 13757 13891 +1%
hnswlib 507 561 +11%
snapvec IVFPQ + rerank 346 359 +4%
FAISS IVFPQ M=192 484 483 0%
snapvec IVFPQ M=192 319 325 +2%
SnapIndex 4-bit 2727 2676 -2%
SnapIndex 3-bit 2717 2688 -1%
SnapIndex 2-bit 2649 2726 +3%
FAISS IVFPQ M=48 143 142 -1%
snapvec IVFPQ M=48 269 267 -1%

Everything except hnswlib sits within 5%. hnswlib is at +11%, which
is within its measured run-to-run variance (noted explicitly in the
new Methodology paragraph).

What changes

  • Updated the competitive table in `docs/benchmarks.md` with the
    fresh numbers (all 10 rows).
  • Added a short Methodology note above the table: single fresh
    process, expected noise envelope per backend, the reason (no OS
    page-cache contamination).

Recall

Unchanged. All backends are deterministic given seeds; recall@10
matches earlier run bit-for-bit.

Test plan

  • Full bench ran end-to-end in a single clean session
  • `mkdocs build --strict` passes
  • CI green on this PR

Re-ran experiments/bench_competitive.py start-to-finish in a single
clean Python session on main (commit 8a28af1, post v0.10.0 merge)
after observing a 56% p50 delta on SnapIndex between the first
multi-session measurement and a later standalone run.

The refreshed table (this commit) sits within +/-5% of the previous
numbers for every row except hnswlib, confirming that the spike was
the first-run outlier we already corrected, not a systemic drift.
All recall numbers are identical run-to-run (determinism tests hold).

Also add a short Methodology note above the table so readers know the
numbers came from one fresh process, and call out the expected
run-to-run noise (<=5% p50 for most rows, ~10% for hnswlib).  This
is what lets the table survive a 're-run it and compare' review.
Copilot AI review requested due to automatic review settings April 20, 2026 13:06

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the benchmark data in docs/benchmarks.md and adds a methodology section describing the measurement process and expected variance. Review feedback suggests refining the reported noise variance for hnswlib to better reflect observed data and identifies several inconsistencies in the descriptive text where hardcoded benchmark values were not updated to match the new table data.

Comment thread docs/benchmarks.md Outdated
Comment on lines +70 to +72
Accelerate with its default thread count. Expected run-to-run noise
on this hardware is <=5% p50 for every row except hnswlib, which
hits +/-10% routinely.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The PR description mentions that hnswlib showed a +11% delta, which is described as being within its expected variance. However, the text here specifies +/-10%. It might be safer to adjust this to ~10-15% to more accurately reflect the observed noise levels on this hardware.

Suggested change
Accelerate with its default thread count. Expected run-to-run noise
on this hardware is <=5% p50 for every row except hnswlib, which
hits +/-10% routinely.
Accelerate with its default thread count. Expected run-to-run noise
on this hardware is <=5% p50 for every row except hnswlib, which
hits ~10-15% routinely.

Comment thread docs/benchmarks.md
on this hardware is <=5% p50 for every row except hnswlib, which
hits +/-10% routinely.

### Reading the table

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The benchmark table has been updated with fresh numbers, but the descriptive text in the following sections (### Reading the table, ### Positioning in plain language, and ### Caveats) still contains hardcoded values from the previous run.

For example:

  • Line 84: (336 vs 475 us) should be (325 vs 483 us).
  • Line 86: 355 us should be 359 us.
  • Line 90: 819 us should be 994 us.
  • Line 92: 13 ms should be 13.9 ms.
  • Line 117: (16 s vs 112 s) should be (17 s vs 110 s).

These should be updated to maintain consistency with the new table data.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refreshes the published “competitive” benchmark table in the documentation using results from a single end-to-end rerun of experiments/bench_competitive.py, and clarifies measurement methodology/noise expectations to address previously observed run-to-run deltas.

Changes:

  • Updated all rows in the competitive benchmark table (p50/p99/build/disk) with fresh-run numbers.
  • Added a Methodology paragraph describing the single-run approach and expected noise envelope (notably for hnswlib).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/benchmarks.md
Comment on lines +46 to +55
| sqlite-vec (brute-force cosine, exact) | **1.000** | 13891 | 18628 | 91.1 | 0.5 |
| hnswlib (M=32, ef_search=128) | 0.994 | 561 | 994 | 104.5 | 45 |
| **snapvec IVFPQ + fp16 rerank (M=192)** | **0.945** | **359** | 457 | 56.9 | 108 |
| FAISS IVFPQ (M=192) [matched-budget] | 0.906 | 483 | 584 | 12.7 | 17 |
| **snapvec IVFPQ no rerank (M=192)** | 0.895 | **325** | 376 | 12.6 | 110 |
| snapvec SnapIndex 4-bit scalar (full-scan) | 0.854 | 2676 | 3164 | 15.4 | 1.1 |
| snapvec SnapIndex 3-bit scalar (full-scan) | 0.736 | 2688 | 3013 | 11.7 | 0.8 |
| snapvec SnapIndex 2-bit scalar (full-scan) | 0.618 | 2726 | 4016 | 8.0 | 0.7 |
| FAISS IVFPQ (M=48) | 0.603 | 142 | 200 | 4.4 | 10 |
| snapvec IVFPQ no rerank (M=48) [matched-budget] | 0.549 | 267 | 350 | 4.3 | 33 |
Comment thread docs/benchmarks.md Outdated
Comment on lines +59 to +64
**Methodology.** All numbers come from a single fresh-process run of
`experiments/bench_competitive.py` so backend-to-backend comparisons
are not contaminated by OS page-cache state inherited from earlier
runs. An earlier multi-session measurement showed a ~56% p50 delta
on SnapIndex between cold and warm runs; the single-run convention
above eliminates that.
Two reviewers flagged that after updating the table values I left the
narrative bullets (Reading the table, Positioning, Caveats) citing
old p50/p99/build numbers.  Align every number in the prose with the
refreshed fresh-process run so the page is internally consistent:

- M=192 matched-budget headline: 1.4x -> 1.5x, 336/475 -> 325/483
- IVFPQ+rerank bullet: 355 us -> 359 us
- hnswlib p99: 819 us -> 994 us
- sqlite-vec cite: 13 ms -> 13.9 ms (so the '~5x faster' claim matches)
- FAISS fit gap: 7x vs 16/112 -> 6.5x vs 17/110
- FAISS M=48 latency bullet: 168 us -> 142 us

Also refine two wording issues from the same review:

- Methodology said 'single fresh-process run' but the bench actually
  runs four per-backend subprocesses under one orchestrator.  Reword
  to 'single end-to-end invocation' and explain the subprocess layout
  so readers know why.
- Expected hnswlib noise was noted as +/-10%; observed +11% delta in
  this run puts it closer to 10-15%.  Update the envelope to match
  reality.
@stffns
stffns merged commit b2b9d2e into main Apr 20, 2026
10 checks passed
@stffns
stffns deleted the bench/clean-rerun-v010 branch April 20, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants