Aggregate the random-access group summary over every dataset - #23
Aggregate the random-access group summary over every dataset#23claude[bot] wants to merge 1 commit into
Conversation
|
Vercel preview for |
The random-access group headline was lifted from the first chart in the group with data at its latest commit -- in practice `feature-vectors/correlated`. That was reasonable when random access had one benchmark; with many, the summary reports whatever that single (and noisiest) dataset did rather than the group. `collectRandomAccessSummary` now aggregates the group's whole result set in one query and reports two labelled aggregates per format: the sum and the geometric mean of the latest per-dataset times, alongside the ratio of geomeans to the fastest format. Comparability across formats needs a snapshot and a coverage rule: - the aggregate is taken at the newest commit with any positive random-access row for the group (all of `random-access-bench`'s datasets and formats come from the same run), and - a format is ranked only if it has a positive value for every dataset measured at that commit, following the compression summaries' "newest complete snapshot" precedent rather than the query summary's missing-series penalty, which works for ratios but would invent a runtime inside an absolute sum or geomean. `RandomAccessGroup` is a singleton group with its own `collect*Summary`, so no other group's headline number changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TAzVGoZhxj8vh8DEx4eR9c Signed-off-by: Claude <noreply@anthropic.com>
5cc904d to
8ebdc97
Compare
|
Superseded by #21, which landed on One deliberate difference worth recording: this PR's geomean was of absolute times, while Generated by Claude Code |
Requested by Connor Tsui · Slack thread
Before. The Random Access summary card showed one number per format, taken from a single chart — the first one in the group with data, in practice
feature-vectors/correlated. So the headline said whatever that one dataset happened to say, including its noise: on the local reproduction below Parquet reads as24.00 msand8.89x, because that dataset spiked, not because random access got 9× slower.After. The card shows two labelled aggregates per format, computed over every dataset in the group: the geomean of their latest times and the total (sum) of them, plus the ratio of geomeans to the fastest format. The same data now reads
2.42 ms geomean · 27.49 ms total · 3.67xfor Parquet, and the footer says which datasets are behind it: "Geomean and total random access time across 4 datasets | Ratio of geomean to fastest (lower is better)". One noisy dataset can no longer carry the headline on its own.That was fine when random access was one benchmark; it is misleading now that it is many.
How
collectRandomAccessSummary(web/lib/summary.ts) replaces the "loop the group's chart links until one has rows" scan with a single query over the whole group. The group's chart names are its dataset names, so they scope the query; per format it then sums and geomeans the latest per-dataset values, and ranks by geomean.SummaryCard.tsxrenders both aggregates with the wordsgeomeanandtotalnext to them, so a reader is not guessing which number is which. The existinggeoMeanhelper is reused unchanged — it already ignores non-positive and non-finite values, so the geomean is over strictly positive values only.Aggregating means choosing a snapshot and a rule for partial data:
random-access-bench's datasets and formats come from the same run, so they share a commit. A same-timestamp commit tie is collapsed withDISTINCT ON (dataset, format)so a tie cannot double-count into the sum.collectCompressionSummary/collectCompressionSizeSummaryrequire a complete pair and drop what is incomplete) rather than the query summary's missing-series penalty, which works because that summary is a ratio; imputing a penalty into an absolute sum or geomean would invent a runtime the benchmark never measured. If no format has complete coverage the summary is omitted, which is what the previous code also did when nothing qualified.Other groups are untouched:
RandomAccessGroupis a singleton group with its owncollect*Summaryarm, so no other headline number moves. TherandomAccessranking's wire fields change fromtimetototal+geomean(/api/groups,/api/group/{slug}); the card is the only consumer in-tree.Tests
web/lib/summary.test.ts— four new unit tests over a mocked pool: multi-dataset sum/geomean and ratio, query scoping to the group's datasets plus the snapshot/DISTINCT ONshape, a format with incomplete coverage being dropped, and an empty group querying nothing.web/lib/groups.test.ts— the Postgres integration assertion now also pins both aggregates; the canonical one-dataset fixture keeps its previous ratios (1.00x / 2.00x), which is the intended behaviour for a one-chart group.web/components/SummaryCard.test.tsx,web/components/GroupSection.test.tsx— updated for the new labelled render.docs/architecture/design-decisions.md— an ADR entry for the snapshot and coverage rules.Local:
pnpm format:check,pnpm lint,pnpm build,pnpm test(348 passed; the 48 Docker-gated tests self-skipped here) andtsc --noEmitall clean. The new SQL was additionally run against a local PostgreSQL 16 withmigrations/applied, which is where the before/after numbers above come from.Out of scope / noted
The hot-vs-cold cache mixing in the random-access measurements (the reason
feature-vectors/correlatedspikes) is not addressed here — it is not fixable from this repo. Details are going back to the Slack thread separately.Generated by Claude Code