Skip to content

perf(index): word-index persist — integer doc remap + chunked hit writes#650

Merged
justrach merged 1 commit into
release/0.2.5828from
perf/wordindex-persist-remap
Jul 4, 2026
Merged

perf(index): word-index persist — integer doc remap + chunked hit writes#650
justrach merged 1 commit into
release/0.2.5828from
perf/wordindex-persist-remap

Conversation

@justrach

@justrach justrach commented Jul 4, 2026

Copy link
Copy Markdown
Owner

First of the write-path items from the perf sweep (the load path got its 3× in #524; writes never had a pass).

What

WordIndex.writeToDisk looked up every posting's disk file id via disk_path_to_id.get(path) — a wyhash of the full path string per posting, millions of times on large repos. #475 flagged the 840ms word.index persist on react; this lookup is its dominant CPU term. doc_id → disk_id is a pure integer remap (path_to_id keeps paths unique), so a []u32 built once in the existing doc-table walk replaces the per-posting hash. Hit records are also batched into 4KB chunks instead of one 8-byte writeAll each.

Quality

  • Byte-identical output: cmp of word.index written by old vs new binaries on the same project — identical, including error.InvalidData semantics for postings referencing stale doc slots.
  • zig build test 23/23 steps green; test-index 174/174.
  • Honest numbers: end-to-end cold snapshot on a 2000-file synthetic corpus moved 4.90s → 4.78s — modest because synthetic paths are short (cheap to hash) and the persist is one slice of the cold pipeline. The perf(cli): persist word index on first invocation — 2.4x faster on react #475-class win scales with path length × posting count (long node_modules-style paths at repo scale).

🤖 Generated with Claude Code

WordIndex.writeToDisk resolved every posting's disk file id through a
StringHashMap keyed by the full path — one wyhash of the whole path
string per posting, millions of times on large repos, flagged as the
dominant CPU term of the 840ms word.index persist in #475. doc_id →
disk_id is a pure integer remap (path_to_id keeps paths unique), so
build a []u32 once in the existing doc-table walk and index it per hit.
Hits are also batched into 4KB chunks instead of one 8-byte writeAll
each.

Output is byte-identical (cmp of word.index written by old and new
binaries on the same project), including error.InvalidData for postings
that reference stale doc slots. zig build test 23/23 steps green;
test-index 174/174. End-to-end cold snapshot on a 2000-file synthetic
corpus: 4.90s -> 4.78s — the big win case (#475's long node_modules
paths × repo-scale posting lists) scales with path length and posting
count, which this corpus intentionally understates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown

Benchmark Regression Report

Thresholds: 10.00% and 50,000 ns absolute delta

NOISE means the percentage threshold was exceeded, but the absolute delta was too small to fail CI.

Tool Base (ns) Head (ns) Delta Abs Delta (ns) Status
codedb_bundle 97059 97665 +0.62% +606 OK
codedb_changes 12852 13240 +3.02% +388 OK
codedb_context 348408 329760 -5.35% -18648 OK
codedb_deps 363 353 -2.75% -10 OK
codedb_edit 58833 48163 -18.14% -10670 OK
codedb_find 3192 3095 -3.04% -97 OK
codedb_hot 31115 28892 -7.14% -2223 OK
codedb_outline 17396 17335 -0.35% -61 OK
codedb_read 15364 14863 -3.26% -501 OK
codedb_search 91554 95007 +3.77% +3453 OK
codedb_snapshot 82742 78093 -5.62% -4649 OK
codedb_status 11043 11335 +2.64% +292 OK
codedb_symbol 57854 56213 -2.84% -1641 OK
codedb_tree 45352 48221 +6.33% +2869 OK
codedb_word 12750 12774 +0.19% +24 OK

@justrach justrach merged commit e5efa56 into release/0.2.5828 Jul 4, 2026
2 checks passed
justrach added a commit that referenced this pull request Jul 5, 2026
Bump semver + npm to 0.2.5828 and round out the changelog entry with
the six commits that landed after the draft was written: searchSymbols
binary-insert + total-order tiebreak (#647, #649), word-index persist
integer remap + chunked writes (#650), call-graph reverse adjacency
precompute (#651), snapshot dual-write clone (#652), ranked-search
line-offset resolution (#653), and scripts/bench-ab.sh (#654). No code
changes beyond the version strings + CHANGELOG.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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