feat(bench): Group A workloads — W2..W6 (sub-phase 9.2)#103
Merged
Conversation
Lands the OLTP-baseline workloads on top of the 9.1 harness:
W2 range scan WHERE secondary >= ? AND <= ?, three width
buckets (100/1k/10k). SQLRite full-scans
(no range index probe yet, see
supported-sql.md:210); SQLite uses the index.
W3 bulk insert BEGIN; INSERT..x100k; COMMIT in one txn.
iter_batched(PerIteration) so each criterion
sample starts from a fresh DB.
W4 single-row Auto-committed INSERTs against a 1k-row
preloaded table. Preload bounds SQLRite's
O(N) bottom-up rebuild at a stable table size.
W5 mixed OLTP 50/50 SELECT-by-PK + UPDATE-by-PK on 100k
rows; even iters SELECT, odd iters UPDATE.
W6 index lookup WHERE secondary = ? on the unique secondary
index — both engines hit the index fast-path.
The plan calls for `BETWEEN x AND y` on W2; SQLRite doesn't ship
BETWEEN yet (`docs/supported-sql.md` "Not yet supported"), so the
workload uses the equivalent `>= AND <=` form. Bumping to BETWEEN
once the engine supports it = `W2.v2`.
Suite wiring:
- benches/suite.rs grew per-workload register_w* fns sharing a
db_path / tempdir_for helper. W2 fans into three criterion
groups (one per width bucket) so each lands as its own
BenchSample row in the JSON envelope.
- W3's register_w3 is iter_batched + a per-sample counter so the
SQLRite WAL sidecar from one sample doesn't collide with the
next. sample_size(10) so a single-driver run finishes in
minutes; override at the CLI for sharper estimates.
- W4 setup pre-loads 1k rows in one BEGIN/COMMIT before the
timed loop so per-iter cost reflects a stable table size,
not a 0..N ramp.
Datasets:
- data.rs gains GroupADataset (100k rows, secondary = unique
permutation of 1..=100k; pre-shuffled pk_probes,
secondary_probes, range_probes_{100,1k,10k}) seeded with
GROUP_A_SEED=43.
- W4 reuses a tiny stable payload (W4_PAYLOAD).
Smoke run (M1 Pro, criterion --warm-up-time 1 --measurement-time 1-2
--sample-size 10):
W1 sqlrite ~19 us / sqlite ~2.4 us — ~8x
W2 100 sqlrite ~37 ms / sqlite ~60 us — ~610x
W2 1k sqlrite ~32 ms / sqlite ~594 us — ~54x
W2 10k sqlrite ~34 ms / sqlite ~6.5 ms — ~5x
W3 sqlrite ~1.35 s / sqlite ~206 ms — ~6.6x (per 100k-row txn)
W4 sqlrite ~7.3 ms / sqlite ~10.9 us — ~673x ⚠
W5 sqlrite ~71 ms / sqlite ~12 us — ~5800x
W6 sqlrite ~15 us / sqlite ~3.1 us — ~5x
Filed SQLR-18 ("Investigate W4 single-row INSERT gap") per the
plan's "if W4 shows >100x gap, file an investigation follow-up
before moving on" exit criterion. Likely culprit is the bottom-up
B-tree rebuild on every COMMIT (CLAUDE.md "B-tree commit
strategy") — informational, not a release gate.
Filed SQLR-17 ("Investigate desktop-build CI hang on Tauri Linux
deps step") for the unrelated 39-min apt-get hang seen on the 9.1
PR's CI run.
Verification:
- cargo fmt --all -- --check clean
- cargo clippy -p sqlrite-benchmarks --all-targets clean
- Full CI-equivalent build / test / doc green
(--exclude desktop / python / nodejs / benchmarks)
- Smoke run end-to-end across W1..W6 + aggregator → JSON envelope
Refs: SQLR-16 (parent execution task), SQLR-18 (W4 follow-up).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 7, 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
Sub-phase 9.2 of
docs/benchmarks-plan.md. Stacks on top of #102 (9.1 harness + W1) to land the OLTP-baseline workloads:WHERE secondary >= ? AND <= ?, 100/1k/10k width bucketsBEGIN; INSERT…×100k; COMMITWHERE secondary = ?(unique probes)Smoke-run numbers (M1 Pro, criterion
--warm-up-time 1 --measurement-time 1-2 --sample-size 10)The W2 ratio collapses as the matching set grows — SQLite scales with the result-set size; SQLRite full-scans the table in constant time regardless of width. That's because the engine's tiny optimizer (
docs/supported-sql.md:210) only probes the index on<col> = <literal>shape — range predicates fall back to full scan. A future range-scan optimizer is the roadmap unlock.Plan-spec adherence
>= ? AND <= ?instead ofBETWEEN x AND y— SQLRite doesn't shipBETWEENyet (it's in supported-sql.md's "Not yet supported" list). Semantically equivalent; both engines parse + execute it cleanly. Bumping toBETWEENonce SQLRite supports it =W2.v2.WorkloadId.versionisv1. JSON envelope tags every sample withW{n}.v{v}.WAL + synchronous=NORMAL + 64 MB cache + temp_store=MEMORYprofile from 9.1.W4 100× heuristic — investigation follow-up filed
The plan's exit criterion for 9.2:
W4 is at ~673× and W5 (which amplifies the same root cause across a 100×-larger preload) is at ~5,800×. Filed SQLR-18 — "Investigate W4 single-row INSERT gap (~673× vs SQLite)" — informational, not a release gate. Likely culprit per the existing project conventions doc is the bottom-up B-tree rebuild on every COMMIT; the task spec lists a flamegraph + roadmap-cross-link plan.
Also filed SQLR-17 — "Investigate desktop-build CI hang on Tauri Linux deps step" for the 39-min apt-get hang seen on the 9.1 PR's CI run, unrelated to this work.
Methodology choices documented in code
iter_batched(BatchSize::PerIteration)with a per-sample counter so SQLRite's WAL sidecar from one sample doesn't collide with the next.sample_size(10)so a single-driver run finishes in minutes.iters_so_far-sized table — SQLRite's O(N) bottom-up rebuild would create a steep ramp through the bench window. Preload puts the table at a stable size.Test plan
cargo fmt --all -- --checkcleancargo clippy -p sqlrite-benchmarks --all-targetscleancargo build / test / doc --workspace --exclude {desktop,python,nodejs,benchmarks}greencargo test -p sqlrite-benchmarks— 5 tests pass (4 inliner + 1 ymd round-trip)cargo bench -p sqlrite-benchmarks --bench suite -- --warm-up-time 1 --measurement-time 1-2 --sample-size 10runs all six workloads end-to-end on both enginesFollow-ups
References
docs/benchmarks-plan.mdbenchmarks/src/workloads/🤖 Generated with Claude Code