feat(bench): harness scaffolding + W1 read-by-PK (sub-phase 9.1)#102
Merged
Conversation
…9.1) First executable code for the SQLRite-vs-SQLite benchmark suite designed in #101. Stands up a `benchmarks/` workspace member with a small `Driver` trait, two engine implementations (SQLRite via `Connection`, SQLite via `rusqlite`-bundled), one workload end-to-end (W1 read-by-PK), a criterion entry point, and an aggregator that collapses `target/criterion/**/estimates.json` into a single results envelope under `benchmarks/results/`. Excluded from CI alongside `sqlrite-desktop` + the SDK cdylibs; runs locally with `make bench`. Plan-doc: - Q1-Q8 resolved on 2026-05-06 and converted to a "Decisions (was: open questions)" section, mirroring the post-resolution shape of `docs/phase-7-plan.md`. Status moved to "approved 2026-05-06 -- 9.1 in flight". - Cleaned up the muddled "Not added to the default exclude list" sentence in the Repository layout section. Harness: - `Driver` trait is small enough to express every planned workload: open / execute / execute_with_params / query_one / query_all. `&self` so drivers are cheap to clone into criterion closures. - SQLRite driver inlines `?` params via SQL formatting (SQLite-side quoting / arity checks unit-tested) -- the engine has no parameter binding yet; that lands as a post-9.6 follow-up. - SQLite driver runs the Q3-tuned profile at open time (WAL + synchronous=NORMAL + 64 MB cache + temp_store=MEMORY) and `prepare_cached` on every hot-path SELECT so we measure execution cost, not per-iter parse cost. - Per-run `TempDir` -- no page-cache / WAL bleed across iterations. - Correctness gate: every workload runs `correctness_check` against sample keys before timing, so a divergent-result "speedup" can't silently land. - Q8 versioning baked in: workloads carry a `WorkloadId { id, name, version }` and the JSON envelope tags every sample with `W{n}.v{v}`. Output: - `BenchSample` per (workload, driver) pair: median + 95% CI + mean + std dev + sample count + ops/s. - `ResultsEnvelope` carries schema_version, run timestamp, host fingerprint (CPU brand, RAM, OS kind + release, arch) and commit info (sha, branch, dirty bit). `aggregate.rs` reads sysctl / /proc / git directly -- no chrono / sysinfo deps. - `benchmarks/results/.gitignore` keeps casual local runs out of git until 9.6 commits the first official pinned-host run. Wiring: - `--exclude sqlrite-benchmarks` added to the four CI cargo commands (build, test, clippy, doc), with a comment explaining why. - `make bench` -> `benchmarks/scripts/run.sh` -> cargo bench + aggregator. `make bench-duckdb` deferred to 9.5. - CLAUDE.md "Workspace layout" + "Commands" sections updated. - `docs/_index.md` plan entry updated to reflect 9.1 shipping. Verification: - `cargo fmt --all -- --check` clean. - `cargo clippy -p sqlrite-benchmarks --all-targets` clean (engine warnings unchanged from baseline). - Full CI-equivalent build + test + doc green (--exclude desktop / python / nodejs / benchmarks). - `cargo test -p sqlrite-benchmarks` -- 5 tests pass (4 inliner + 1 ymd-from-days round-trip). - End-to-end run with `--warm-up-time 1 --measurement-time 2 --sample-size 10`: SQLRite ~12 us/op, SQLite ~2.5 us/op (~5x gap, driven by SQLRite re-parsing per call). Aggregator wrote a 2-sample JSON envelope. Refs: SQLR-4 (design), SQLR-16 (execution), #101. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First executable code for the SQLRite-vs-SQLite benchmark suite designed in #101 (SQLR-4). Sub-phase 9.1 of the plan.
> **Decided: …**blockquote at the top. Seedocs/benchmarks-plan.md.benchmarks/workspace member with a smallDrivertrait, two engine impls (SQLRite viaConnection, SQLite viarusqlite-bundled), one workload (W1 read-by-PK), a criterion entry point, and an aggregator that walkstarget/criterion/**/estimates.jsoninto a single results envelope underbenchmarks/results/.sqlrite-benchmarksalongsidesqlrite-desktop+ the SDK cdylibs; runs locally viamake bench.Plan-doc decisions (Q1–Q8)
synchronous=NORMAL+64 MB cache; default-mode is opt-in secondary--features duckdb); Group B onlydocs/benchmarks.md+ raw JSON inbenchmarks/results/version(W1.v1,W1.v2, …)Harness shape
Drivertrait is small enough to express every planned workload (open / execute / execute_with_params / query_one / query_all).&selfreceiver so drivers are cheap to clone into criterion closures.?params via SQL formatting — the engine has no parameter binding yet; the inliner is unit-tested for arity, escaping, and?-in-strings. Once the engine grows real binds, this driver flips to the bound path and a workloadvbump captures the methodology change.synchronous=NORMAL+ 64 MB cache +temp_store=MEMORY) andprepare_cachedon every hot-path SELECT — so we measure execution cost, not per-iter parse cost.TempDir— no page-cache / WAL bleed across iterations.correctness_checkagainst sample keys before timing, so a divergent-result "speedup" can't silently land.WorkloadId { id, name, version }and the JSON envelope tags every sample withW{n}.v{v}.JSON output (locked in this PR)
BenchSampleper (workload, driver) pair: median + 95% CI + mean + std dev + sample count + ops/s.ResultsEnvelopecarriesschema_version,run_started_at(RFC 3339),run_duration_secs, host fingerprint (CPU brand, RAM, OS kind + release, arch), and commit info (sha, branch, dirty bit).aggregate.rsreadssysctl//proc/gitdirectly — nochrono/sysinfodeps.benchmarks/results/.gitignorekeeps casual local runs out of git until 9.6 commits the first official pinned-host run.End-to-end smoke run (illustrative — not the official 9.6 publication)
About a 5× gap on the read-by-PK hot path, driven by SQLRite re-parsing the SQL on every iteration. That's the baseline a future "prepared-statement support" follow-up needs to move.
Test plan
cargo fmt --all -- --checkcargo clippy -p sqlrite-benchmarks --all-targetsclean (existing engine warnings unchanged from baseline)cargo build / test / doc --workspace --exclude {desktop,python,nodejs,benchmarks}greencargo test -p sqlrite-benchmarks— 5 tests pass (4 inliner + 1 ymd-from-days round-trip)cargo bench -p sqlrite-benchmarks --bench suiteruns end-to-end; aggregator wrote a 2-sample JSON envelopemake benchtarget wired throughscripts/run.sh--exclude sqlrite-benchmarksadded to all four cargo commands in.github/workflows/ci.ymlFollow-ups
W1.v2bump.docs/benchmarks.md+ first official pinned-host JSON committed + top-level README "Benchmarks" section.References
docs/benchmarks-plan.mddocs/roadmap.md"Possible extras"🤖 Generated with Claude Code