perf(search): PR A — nudge O(1), BM25 single-map, tier-1 keyed sort (#1 #3 #6) - #660
Conversation
#3 #6) Three behavior-preserving optimizations on the per-query search/rank path, identified by the perf audit and adversarially verified: #1 (mcp.zig, appendSearchSymbolNudge): the bare-identifier nudge did a full O(U+S) symbol scan (searchSymbols scans the whole symbol_index AND outlines every call) just to test existence. Switched to findAllSymbols — the same helper codedb_symbol uses: ensureSymbolIndex + O(1) symbol_index.get, with the outline scan only when !symbol_index_complete. Output byte-identical (the nudge only checks results.len and prints the query string). #3 (explore.zig, BM25 posting loop): dropped the doc_tf hashmap. doc_best_line already accumulates .count identically per posting, so df = doc_best_line.count() and tf = entry.value_ptr.count — one map instead of two, and the redundant per-doc .get() re-lookup is gone. Values bit-identical. #6 (explore.zig, tier-1 sort): the comparator hashed 4 strings + touched 2 atomics per comparison. Precompute (count, len) per candidate once in O(C) (mirroring tier0_order), then sort a struct-key array — identical predicate (count desc, len asc) and input order, so ranking is unchanged. Also stops the comparator corrupting ContentCache hit/miss stats. zig build test: full suite green (0 failures). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Benchmark Regression ReportThresholds: 10.00% and 50,000 ns absolute delta
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e589b3d31a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .max_results = 1, | ||
| }; | ||
| const results = explorer.searchSymbols(spec, alloc) catch return; | ||
| const results = explorer.findAllSymbols(query, alloc) catch return; |
There was a problem hiding this comment.
Avoid materializing every duplicate symbol for the nudge
When the bare query is a common symbol such as init or main in a large repo, findAllSymbols duplicates every matching path/name/detail even though this branch only checks results.len. That puts O(matches) allocation/free work in front of each text codedb_search; the previous searchSymbols call was capped with max_results = 1, so materialization was bounded. Use an existence check or capped exact lookup for the nudge.
Useful? React with 👍 / 👎.
Three behavior-preserving perf optimizations on the per-query search/rank hot path, from the perf audit and adversarially verified (produced by a 3-attempt swarm; winner independently re-verified).
Changes
#1 —
mcp.zigappendSearchSymbolNudge: the bare-identifier nudge did a full O(U+S) symbol scan (searchSymbolsscans the wholesymbol_indexandoutlineson every call) just to test whether the query names an indexed symbol. Now usesfindAllSymbols— the same helpercodedb_symboluses:ensureSymbolIndex+ O(1)symbol_index.get, falling back to the outline scan only when!symbol_index_complete. Output is byte-identical (the nudge only checksresults.lenand prints the query string).#3 —
explore.zigBM25 posting loop: dropped thedoc_tfhashmap.doc_best_linealready accumulates.countidentically per posting, sodf = doc_best_line.count()andtf = entry.value_ptr.count. Two maps → one, and the redundant per-doc.get()re-lookup is eliminated. Values bit-identical.#6 —
explore.zigtier-1 sort: the comparator hashed 4 strings + touched 2 atomics per comparison. Now precomputes(count, len)per candidate once in O(C) (mirroring the existingtier0_orderpattern) and sorts a struct-key array — identical predicate (count desc, len asc) and identical input order, so ranking output is unchanged. Bonus: stops the comparator corruptingContentCachehit/miss stats via repeated atomic reads.Validation
zig build test— full suite green, 0 failures.Part of the search-latency cluster from the Fable-5 perf audit. Independent of #659.
🤖 Generated with Claude Code