Skip to content

fix: read the criterion output a cached baseline directory breaks apart - #193

Merged
hicksy merged 2 commits into
mainfrom
fix/criterion-baseline-comparison
Aug 18, 2026
Merged

fix: read the criterion output a cached baseline directory breaks apart#193
hicksy merged 2 commits into
mainfrom
fix/criterion-baseline-comparison

Conversation

@hicksy

@hicksy hicksy commented Aug 18, 2026

Copy link
Copy Markdown
Member

What this changes

criterion-benchmarks fails whenever the job gets a cache hit. A restored target/criterion has the per-benchmark base directory but not the sample.json in it, and criterion prints the resulting read failure to stdout, in the middle of the line the bencher formatter is writing. The workflows now clear target/criterion before the run, and the parser reads a split line as well as a whole one.

A second problem surfaced alongside it: a run that lost some benchmarks compared the rest and exited 0, so the check went green while the comment it posted said the result should not be trusted. That now exits 4 and fails the step, keeping the table that names what went missing.

Closes #192.

Note for whoever merges feat/vector-indexes: 5533bae on that branch adds the same rm -rf inline on the cargo bench line. Keep one, not both.

Checklist

  • Tests added or updated
  • cargo fmt --check and cargo clippy -- -D warnings pass locally
  • CHANGELOG.md updated if this is a user-visible change CI only, nothing user-visible
  • Linked issue, discussion, or a short note explaining the motivation
  • I agree my contribution is licensed under the project's terms
    (MIT License and Apache License, Version 2.0)

DynamoDB compatibility note

Not applicable.

hicksy added 2 commits August 18, 2026 14:10
criterion-benchmarks has been failing with `no criterion results parsed,
nothing to compare`. A cache hit brings benchmarks/target back with
target/criterion in a half state: the per-benchmark base directory is there but
the sample.json inside it is not. Criterion takes the directory alone as a
baseline to compare against, cannot read it, and prints the error to stdout
rather than stderr. It lands in the middle of the line the bencher formatter
was writing, so all thirteen results arrive as a header and a measurement on
separate lines and the single-line regex matches none of them.

Both benchmark workflows now clear target/criterion before the run. The
baseline for the comparison comes from the benchmark-data branch, so
criterion's own on-disk one is only ever leftovers from an unrelated PR.

The parser reads the header and the measurement separately, so anything
criterion prints between the two no longer takes the whole comparison with it.
A name with no measurement behind it is dropped instead of picking up the next
benchmark's figure, which keeps a benchmark that produced nothing reported as
missing. The refresh workflow and the local runner each kept their own copy of
the old regex and both now call the one in compare_criterion.py, with the
refresh failing rather than storing an empty baseline for every later
comparison to skip over. The parser has tests, and CI runs them.
…ing it

A run that produced results for some benchmarks and not others compared the
ones it had and exited 0, so the check went green while the comment it posted
said "treat this as a failed comparison rather than a pass". The comparison
already worked out which benchmarks went missing; it just had nowhere to put
the answer. build_report now returns that list and the run exits 4, which both
workflows read as a failure that still has a table worth showing, unlike the
exit 1 that means no comparison happened at all.

The missing-benchmark warning also sat behind the regression warning in an
if/elif chain, so a run that both regressed and lost benchmarks only ever
mentioned the regression. They are independent now, and missing takes
precedence over the advisory regression exit.

Tests cover build_report and the exit codes the workflows branch on. The
bencher fixtures carried criterion's progress notes on stdout, where it writes
them with eprintln! and tee never sees them.
@github-actions

Copy link
Copy Markdown
Contributor

Criterion Benchmark Results

Baseline is the per-benchmark median of the last 5 stored runs, so one unusually fast or slow runner cannot skew the comparison. The range column is the spread across those runs.

Benchmark Baseline (ns/iter) Range Current Change
batch_execute_statement_25 615,329 new
batch_get_item_100 1,389,601 814,524 - 1,451,464 1,370,694 -1.4%
batch_write_item_25 1,119,577 533,898 - 1,182,554 918,801 -17.9%
delete_item 51,384 26,334 - 53,068 44,300 -13.8%
get_item 14,455 8,000 - 15,127 14,023 -3.0%
put_item/put_item/large 269,725 115,520 - 280,567 261,080 -3.2%
put_item/put_item/medium 44,503 19,445 - 46,845 34,884 -21.6%
put_item/put_item/small 25,143 10,759 - 26,885 20,080 -20.1%
query_base_table 1,093,125 666,833 - 1,164,732 1,121,233 +2.6%
query_gsi 25,592 12,359 - 26,517 21,319 -16.7%
scan_with_filter 8,217,608 5,182,664 - 8,785,317 8,711,530 +6.0%
transact_write_items_4 257,350 112,673 - 267,776 215,445 -16.3%
update_item 163,483 85,461 - 185,342 162,476 -0.6%

All benchmarks within 50% of the 5-run median.

Runs in the baseline
  • runs/2026-06-26-e066fc0
  • runs/2026-07-05-7d5fd8a
  • runs/2026-07-24-f7e7d96
  • runs/2026-07-30-bc2a16c
  • runs/2026-07-30T220642Z-be8bfbc

@hicksy
hicksy merged commit 7a92456 into main Aug 18, 2026
22 checks passed
@hicksy
hicksy deleted the fix/criterion-baseline-comparison branch August 18, 2026 13:39
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.

criterion-benchmarks fails on every PR because it has no baselines to compare against

1 participant