Skip to content

perf(sdk): stop cloning turn streams in analyze hot paths#422

Open
willwashburn wants to merge 1 commit into
mainfrom
claude/submit-pr-review-b1sse
Open

perf(sdk): stop cloning turn streams in analyze hot paths#422
willwashburn wants to merge 1 commit into
mainfrom
claude/submit-pr-review-b1sse

Conversation

@willwashburn
Copy link
Copy Markdown
Member

Summary

Closes #325. Aggregate per-session / per-file groups in the analyze hot paths by &TurnRecord instead of cloning the full record. TurnRecord carries a Vec<ToolCall> plus optional file lists, so these clones are not cheap.

  • overhead.rs: per-file filter now collects Vec<&TurnRecord> and routes through a new internal attribute_claude_md_refs. The public attribute_claude_md is unchanged — it adapts via a single ref collect. Biggest win: every Claude turn used to be cloned ~2× and every Codex/OpenCode turn ~1× across the default file candidates.
  • hotspots.rs: the per-session group is IndexMap<String, Vec<&TurnRecord>>. Private attribute_session and index_tool_results now take &[&TurnRecord].
  • quality.rs: per-session aggregation borrows turns; private infer_outcome_refs / compute_one_shot_rate_refs do the work. The public infer_outcome and compute_one_shot_rate keep their existing signatures and adapt via a single ref collect.
  • compare.rs: hoist the model-name clone above the three entry/or_default calls so we allocate one owned String per new model (instead of four per turn). by_model_category is now the canonical insertion gate since model_set and model_totals may be pre-seeded by the model filter.

The describe_applies_to follow-up the issue mentioned is already in main (uses SourceKind::wire_str returning &'static str).

Test plan

  • cargo build --workspace
  • cargo test --workspace — all 657 SDK tests pass, plus CLI / sdk-node suites
  • cargo clippy --workspace --all-targets — no new warnings from this change

🤖 Generated with Claude Code


Generated by Claude Code

Aggregate per-session/per-file groups by `&TurnRecord` instead of cloning
the full record. The biggest win is `overhead.rs`, which used to clone
every applicable turn per file (~3x for Claude turns with two CLAUDE.md
candidates plus AGENTS.md cross-checks).

- `overhead`: per-file filter into `Vec<&TurnRecord>`; route through a
  new internal `attribute_claude_md_refs` so the public
  `attribute_claude_md` is a thin wrapper.
- `hotspots`: `IndexMap<String, Vec<&TurnRecord>>` for the per-session
  groups; private `attribute_session` / `index_tool_results` now take
  `&[&TurnRecord]`.
- `quality`: per-session groups borrow turns; private
  `infer_outcome_refs` / `compute_one_shot_rate_refs` drive the work and
  the public functions adapt via a single ref collect.
- `compare`: hoist the model-name clone above the three `entry` calls so
  we allocate once per *new* model, not four times per turn.

Closes #325.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4e8454cc-a435-49d2-b535-58016f12e430

📥 Commits

Reviewing files that changed from the base of the PR and between 67d7255 and 23a4003.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • crates/relayburn-sdk/src/analyze/claude_md.rs
  • crates/relayburn-sdk/src/analyze/compare.rs
  • crates/relayburn-sdk/src/analyze/hotspots.rs
  • crates/relayburn-sdk/src/analyze/overhead.rs
  • crates/relayburn-sdk/src/analyze/quality.rs

📝 Walkthrough

Walkthrough

This PR eliminates TurnRecord cloning across the analyze module's memory-intensive hot paths by switching per-session and per-file aggregations to use borrowed references. The refactoring introduces a reference-based Claude Markdown attribution helper and updates hotspots, quality, compare, and overhead modules to operate on Vec<&TurnRecord> views, reducing working-set memory pressure while preserving all behavior.

Changes

TurnRecord reference-based aggregation optimization

Layer / File(s) Summary
Claude Markdown reference-based attribution refactoring
crates/relayburn-sdk/src/analyze/claude_md.rs
Introduces internal attribute_claude_md_refs(files: &[ParsedClaudeMd], turns: &[&TurnRecord], pricing: &PricingTable) helper to accept borrowed turn slices and build per-session indices without cloning. Public attribute_claude_md pre-borrows input turns and delegates to the new helper.
Hotspots per-session indexing optimization
crates/relayburn-sdk/src/analyze/hotspots.rs
Per-session indexing now stores Vec<&TurnRecord> references instead of cloning. Updates attribute_session and index_tool_results helper signatures to operate on borrowed turn slices (&[&TurnRecord]).
Quality analysis reference-based aggregation
crates/relayburn-sdk/src/analyze/quality.rs
Groups turns per session as &TurnRecord reference slices and delegates to new internal infer_outcome_refs and compute_one_shot_rate_refs helpers. Public wrappers build borrowed views internally; public signatures unchanged. Updates ending_role and trailing_failure_streak helpers to operate on reference slices.
Compare table accumulation optimization
crates/relayburn-sdk/src/analyze/compare.rs
Main aggregation loop now derives model as &str and applies allow-list checks on the borrowed value. Population of model_set/model_totals/category_set occurs only on first insertion into the canonical map; accumulation uses get_mut on pre-created entries instead of entry().or_default() with per-iteration cloning.
Overhead attribution integration
crates/relayburn-sdk/src/analyze/overhead.rs
Per-file filtering now collects matching turns as Vec<&TurnRecord> and calls attribute_claude_md_refs instead of the prior value-based attribute_claude_md with full clones. Eliminates the 3× overhead turn cloning bottleneck.
Changelog update
CHANGELOG.md
Documents hot-path analysis optimization: per-session/per-file grouping now aggregates by reference instead of cloning TurnRecords, reducing working-set memory for overhead, hotspots, quality, and compare while preserving behavior.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🐰 A hop through memory springs so light,
No clones of turns from morn to night,
By ref we bound, the workset freed,
Hot paths now run with newfound speed!
Each turn's a view, no dupes remain—
Less alloc joy, less malloc pain. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'perf(sdk): stop cloning turn streams in analyze hot paths' is concise, specific, and clearly summarizes the main performance optimization in the changeset.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the rationale, implementation details across all modified files, test results, and linking to issue #325.
Linked Issues check ✅ Passed The PR fully addresses all coding objectives from issue #325: eliminates cloning in overhead.rs, hotspots.rs, quality.rs, and compare.rs by using &TurnRecord references; maintains behavioral parity; and passes all tests.
Out of Scope Changes check ✅ Passed All changes in the PR are scoped to the objectives of issue #325: refactoring hot-path analysis functions to use references instead of clones. CHANGELOG.md addition documents the change appropriately.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/submit-pr-review-b1sse

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

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

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.

Rust perf: stop cloning whole turn streams in analyze hot paths

2 participants