perf(daemon): drop the per-log-line String reallocation in the log task - #3102
perf(daemon): drop the per-log-line String reallocation in the log task#3102phil-opp wants to merge 1 commit into
Conversation
For every log line of every spawned node, the file-logging task rebuilt the line with `content.lines().fold(String::new(), ..)`, heap-allocating a fresh String and copying the whole line byte-for-byte. `content` is already an owned single logical line (the reader stops at the first `\n`), so the fold was only stripping the trailing line terminator. Replace it with an in-place `strip_trailing_newline` helper that pops a trailing `\n`/`\r\n` from the owned buffer, avoiding the allocation and copy on the log hot path. Behavior is byte-for-byte identical for the single-line inputs the reader produces, guarded by a unit test that diffs the helper against the old fold over newline/CRLF/empty/truncated cases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K1Fmp8pELuTiPGTStomkZj
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
|
🤖 Automated review by Claude Code — fully automated review, not vetted by a human. No issues found. I verified the optimization against the code.
Generated by Claude Code |
Issue
The daemon's per-node file-logging task ran this for every log line of every spawned node (
binaries/daemon/src/spawn/prepared.rs):contentis an ownedStringmoved out of theLogLineand not used afterward. It holds a single logical line —read_capped_linestops at the first\n— so this fold does nothing but strip the trailing newline, yet it heap-allocates a brand-newStringand copies the entire line byte-for-byte. On a node logging at high frequency that's an allocation + full copy per line, on the log hot path, for no benefit.Fix
Introduce a small
strip_trailing_newline(String) -> Stringhelper that pops a trailing\n(and a preceding\r) from the already-owned buffer in place, and use it instead of the fold. No allocation, no copy.For the single-line inputs the reader produces, the result is byte-for-byte identical to
content.lines().next().Validation
strip_trailing_newline_matches_lines_for_single_line, which diffs the helper against the old.lines().fold(...)implementation across\n,\r\n, bare\r, empty, mid-line\r, trailing-spaces, and truncated-marker cases.cargo +1.97.1 fmt -p dora-daemon -- --check— clean.cargo +1.97.1 clippy -p dora-daemon -- -D warnings— clean.cargo +1.97.1 test -p dora-daemon strip_trailing— passes.🤖 Generated with Claude Code
Generated by Claude Code