Skip to content

perf(pr-context): build the include-coupling table once per call, not once per changed file (~5.8x faster) - #395

Merged
joyful-ii-V-I merged 1 commit into
mainfrom
lane/prcontext-hoist
Oct 13, 2026
Merged

joyful-ii-V-I merged 1 commit into
mainfrom
lane/prcontext-hoist

Conversation

@joyful-ii-V-I

@joyful-ii-V-I joyful-ii-V-I commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

--pr-context rebuilt the static include-coupling table once per changed file, and again on every pass of its trim ladder. The table depends only on the ingest, so this was loop-invariant work: about 87% of --pr-context's time. Found while profiling legendcoveragecheck (#394).

The change: a lazily built CoCouplingCache in src/gitmine.h, keyed on the ingest, with an EXPECTS that it is only used with that ingest. writePrContext, writeSituation and computeSituationFacts share one cache per call; single-probe callers behave as before. Not changed: multi-root --pr-context still builds once per root.

Output: byte-identical on all 49 argv:

  • 29 in-scope CLI runs: --pr-context at HEAD~1/~5/~30 on four repos (ripwire, hono, tmux, textual), budget variants, --situ, --cochange;
  • 6 MCP calls;
  • 3 dirty-tree runs: --handoff, bare --situ, bare --pr-context;
  • 11 out-of-scope runs.

Speed: --pr-context=HEAD~30 on this repository went from 49.5/45.8 s to 8.7/7.7 s, two interleaved runs each, about 5.8× faster.

Checks:

  • 22 targeted gates pass.
  • ASan (llvm@22): 10 gates and the HEAD~30 run show zero sanitizer reports, and the output still matches base.
  • --quality-delta gates 0; prereview passes.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Performance
    • Pull request context and situation reports now reuse coupling analysis across related checks, reducing repeated calculations.
    • Co-change partner classifications remain unchanged, so these performance improvements do not alter the reported results.

…probe

cochangePartners built a whole-ingest StaticIncludeCoupling (buildPreciseIncludeAdj
over every include) on EVERY call. Its only input is the ingest, so the multi-probe
callers (--pr-context, --situ text and facts) rebuilt the same graph once per
changed file, and --pr-context again per trim-ladder render pass: ~87% of a
--pr-context=HEAD~30 run on ripwire.

New CoCouplingCache holds one lazily-built coupling keyed on the ingest it was
made for (EXPECTS on a mismatched ingest); the precomputed-sets overload takes an
optional pointer to it, and writePrContext / writeSituation /
computeSituationFacts pass one per call. Single-probe callers (CLI --cochange,
MCP cochange) keep a one-off local cache. Output is byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: redhat-et/ripwire/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5414b561-3172-498e-b49e-5fb4e4ba27ee
📥 Commits

Reviewing files that changed from the base of the PR and between a88f03d and 82cd0bd.

📒 Files selected for processing (3)
  • src/gitmine.h
  • src/prcontext.h
  • src/situ.h

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📝 Walkthrough

The precomputed co-change partner lookup now supports a reusable, lazy StaticIncludeCoupling cache. Context and situation operations create a cache and pass it to their co-change probes.

Changes: Co-Change Coupling Cache

Layer / File(s) Summary
Cache-backed co-change lookup
src/gitmine.h
CoCouplingCache lazily constructs and reuses StaticIncludeCoupling for its IngestResult. The precomputed-sets cochangePartners overload accepts an optional cache and creates a local cache when none is supplied.
Reuse cache across context and situation probes
src/prcontext.h, src/situ.h
writePrContext, writeSituation, and computeSituationFacts create and pass a shared cache to their cochangePartners probes.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Refactor

Suggested reviewers: barefootski

Merge Risk: ⚪ Minimal · up to 82cd0

Context and situation probes now reuse a coupling table without changing their ingest source. No concrete correctness or availability risk is evident, so the change is mergeable.

Pre-merge checks · Passed 4
Passed Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the performance change: reusing the include-coupling table once per call instead of rebuilding it for each changed file, with the reported speedup.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@joyful-ii-V-I
joyful-ii-V-I merged commit a87470c into main Oct 13, 2026
74 of 75 checks passed
joyful-ii-V-I pushed a commit that referenced this pull request Oct 13, 2026
… lane/legendcov-speed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
joyful-ii-V-I pushed a commit to lennix1337/ripwire that referenced this pull request Oct 20, 2026
Version 0.6.7 -> 0.6.8 in CMakeLists.txt; the CHANGELOG [Unreleased] section becomes
[0.6.8] - 2026-10-19 with a fresh empty [Unreleased] above it, a summary (two grading
methods, 0.6.5 -> 0.6.7 -> 0.6.8, credits) and entries for the changes whose lanes merged
without one (--for stops when complete + soft --token-budget, the owner body, the startup
git check, --pr-context redhat-et#395, the dangling-reference fences). The closure/bridge "Fixed"
entry, which fixed features that exist only in this release, is now an Added entry. The
README gets the 0.6.8 release-notes paragraph, the "Latest" line and the Windows snippet
version. No logic changes; kParserVer 198 / kCacheVersion 36 unchanged.

Co-Authored-By: Claude Opus 5.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.

2 participants