Skip to content

DDIR bench spike, parked: findings and open items - #860

Draft
frankmcsherry wants to merge 25 commits into
master-nextfrom
bench-spike
Draft

DDIR bench spike, parked: findings and open items#860
frankmcsherry wants to merge 25 commits into
master-nextfrom
bench-spike

Conversation

@frankmcsherry

Copy link
Copy Markdown
Member

A draft PR to hold the benchmark side spike that followed #858, so its findings and open items are public rather than private notes. Not for merging as is.

  • interactive/bench/reports/2026-09-06-open-items.md — the disposition of everything on the branch: six corgi-backend commits ready to land as a small PR, the merge decision (row-wise fast path vs the survey merge on survey-merge, and what the latter waits on in corgi), open items with a measured shape, things tried and recorded as no.
  • interactive/bench/reports/2026-09-04-findings.md — twenty sections of findings (the reduce is the cost; corgi vs vec; four-worker scaling; TPC-H/LDBC; the merge, batched; sort breadth-first).
  • interactive/bench/bench.py — the harness, driving the live server binary; the reports are its record.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T

frankmcsherry and others added 25 commits September 6, 2026 16:58
…rofile

`interactive/bench/bench.py` runs every workload as a session on the server
binary (install, load, tick, tick R) across backends, worker counts and
repetitions, and writes JSONL + markdown reports named by date and revision.
Workloads: scc, reach, kcore, stable, tour, adt, ast, unnest on seeded random
graphs at three scales, and the 33 AoC parts. `--profile` records one session
under samply.

Reports so far: the small-scale sweep, and a first reading of an scc/corgi
profile with candidate hot spots (find_ranges seeking from scratch per needle;
`CorgiChunk::advance` materializing and re-advancing repeated times).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
…ngs so far

unnest's 3.2s "load" was 91% stderr writes from its inspect tap, tour's 10s
likewise. The harness now times stripped copies of the programs. Findings
across the scc/ast/unnest profiles and the sweeps are in
reports/2026-09-04-findings.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
`CorgiChunk::advance` materialized a `Product<u64, PointStamp>` per row, joined
it with the frontier (another allocation past one coordinate), sorted the
owned times, and cloned the survivors. A batch holds few distinct times, so
rows now carry an index into a per-batch table of distinct source times (kept
as columnar refs, binary-searched) and their advanced forms; the owned time
is built once per distinct time. One scratch buffer serves every group, where
a fresh `Vec` per group had been an allocation per row.

scc on corgi at medium scale: initial epoch 1.99→1.90 s, churn epoch 58.0→56.2 ms;
kcore, reach and tour unchanged. Corgi gate passes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
…tput block

The projection's operand shapes are static per join, as they are for the
linear operators' Plan; the graph is now pinned at the first block's shapes
and reused. Small effect on its own (one block per install on tiny inputs is
also one compile), but it removes the per-block scratch lowering and type
check from the join's hot loop.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
`compile` asks `shape_of_term` for the shapes of an `if`'s branches (a
`case`'s arms, a fold's parts, ...) before compiling them, and each ask is a
full scratch lowering of that subterm plus a `corgi::shape_of` evaluation. So
nested conditionals were re-lowered once per enclosing level — 3^depth in all.
AoC day 7, five `if`s deep, spent half of every install there.

The shape memo is keyed by term address, environment shapes and expected
shape, and lives only for the span of the outermost `compile` /
`shape_of_term` on the thread, so an address can never be met again with a
different term behind it. Day 7 part 1's tick on corgi: 7.0 → 3.4 ms; the
AoC suite and all tests pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
cc.ddp propagates the least reachable node id over the edges read as
undirected, staggered by magnitude as scc does; triangles.ddp counts a < b < c
closures with two joins and no recursion. Both are in the corgi gate and in
the benchmark harness, where the join-only program shows corgi's widest lead
(2.4x per churn epoch at one worker).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
…findings

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
…n stamps

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
`collect_present` probed every chunk of the arrangement with the whole change
set. A batch's chunks partition its key range, so each chunk now takes only
the needles inside its own range (two partition_points on the sorted change
set) and a chunk with none is skipped. Nothing changes at medium scale (one
chunk per batch); at 1M nodes / 2M edges on corgi, one worker, scc's churn
epoch goes 700 -> 657 ms and cc's 178 -> 160 ms. Corgi gate passes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
…es in the merge)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
…mpare per row

`merge_present` verifies that no id in a run covers two real keys before it
trusts id order. For a non-leaf key that was a structural `compare_at` per
adjacent pair, and every row of a group shares its id with its predecessor,
so nearly every row of every retire paid one. One `compare_adjacent` pass
over the key column answers the same question. ast_hier (a `(bucket, hash)`
key) on corgi at medium, one worker: initial epoch 491 -> 422 ms, churn epoch
19.7 -> 17.0 ms; leaf-keyed programs are not on this path and are unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
`CorgiChunk::merge` ordered its two-pointer walk with `compare_at` per row, a
shape walk per comparison. When both chunks' keys and values are bare `u64`
leaves — integer keys are their own identifiers, and integer values are the
common case — or the value is unit, as under `distinct`, structural order is
one or two integer compares read straight off the lanes. Other shapes keep
`compare_at`.

Medium scale on corgi, one worker, initial epoch / churn epoch: scc 1.90 s ->
1.72 s / 56 -> 54 ms, cc 587 -> 534 ms / 15.4 -> 14.7 ms, kcore 281 -> 253 ms /
2.3 -> 2.1 ms, reach 172 -> 168 ms / 10.3 -> 9.6 ms. Test suite passes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
…-counted initial epochs

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
Disposition of everything the spike left behind: the six backend commits
ready to land, the merge decision (row-wise fast path vs survey merge, and
what the latter waits on), the open items with a measured shape, the
things tried and recorded as no, and the loose ends elsewhere.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDsLC46QQW9aBrksaWad6T
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.

1 participant