Skip to content

perf: dep_graph: serve edge lists in place from the retained file bytes [-0.64% incr-unchanged]#59

Open
xmakro wants to merge 2 commits into
perf/dep-graph-append-onlyfrom
perf/dep-graph-edges-in-place
Open

perf: dep_graph: serve edge lists in place from the retained file bytes [-0.64% incr-unchanged]#59
xmakro wants to merge 2 commits into
perf/dep-graph-append-onlyfrom
perf/dep-graph-edges-in-place

Conversation

@xmakro

@xmakro xmakro commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Based on #44 (append-only save via wholesale carry of the record region). Split out of that PR to be measurable on its own; independent of the skip-edge-collection sibling PR #58.

Decoding used to copy every edge byte out of the file into a freshly allocated buffer, the largest allocation and copy of the load. The file stays mapped for the whole session anyway (the carry copies its record region forward), so serve the edge lists directly from the retained bytes: the on-disk varint encoding was already the in-memory representation, and each node's edge header now records a position in the file instead of a position in the copied buffer. Decoding a record shrinks to reading its fixed header and skipping over the edges. The fixed-size overread at the end of an edge list stays in bounds because the footer always follows the records. On Windows, where the mapping must not outlive the load because the save renames over the mapped file, the bytes are copied out once instead.

Local rustc-perf (primary crates, instructions:u), this change alone against the #44 branch:

scenario delta
incr-unchanged -0.64%
incr-patched -0.43%
full / incr-full -0.04% / -0.03% (control)

27 of 60 cells improved by at least 0.25%, 0 regressed.

Validation: 20 generations each of incr-unchanged, of alternating real edits, and of alternating edits under -Zincremental-verify-ich, all crossing the compaction boundary: every generation clean.

xmakro and others added 2 commits July 25, 2026 15:13
Compaction was triggered only by a fixed generation cap: after eight carried
generations the file is rewritten fresh, whatever its actual state. Track the
live record bytes exactly in the footer, as an O(changed) delta like the other
counts, and rewrite once the record region exceeds twice its live bytes.
High-churn graphs compact as often as before, while low-churn graphs carry for
up to sixteen generations instead of eight, avoiding the periodic compaction
spikes the fixed cap forced on them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Decoding used to copy every edge byte out of the file into a freshly
allocated buffer, the largest allocation and copy of the load. The file
stays mapped for the whole session anyway (the carry copies its record
region forward), so serve the edge lists directly from the retained bytes:
the on-disk varint encoding was already the in-memory representation, and
each node's edge header now records a position in the file instead of a
position in the copied buffer. Decoding a record shrinks to reading its
fixed header and skipping over the edges. The fixed-size overread at the
end of an edge list stays in bounds because the footer always follows the
records. On Windows, where the mapping must not outlive the load because
the save renames over the mapped file, the bytes are copied out once
instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@xmakro xmakro changed the title perf: dep_graph: serve edge lists in place from the retained file bytes perf: dep_graph: serve edge lists in place from the retained file bytes [-0.64% incr-unchanged] Jul 26, 2026
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