Skip to content

perf(string): fuse accumulator concat chains - #8497

Draft
proggeramlug wants to merge 2 commits into
mainfrom
perf/iso-miss-envelope
Draft

perf(string): fuse accumulator concat chains#8497
proggeramlug wants to merge 2 commits into
mainfrom
perf/iso-miss-envelope

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • recognize s = s + a + b + ... for proven string accumulators in local, captured, and module-global slots
  • lower the accumulator and suffix operands left-to-right into one rooted runtime call
  • reuse a unique accumulator's existing capacity, or allocate the complete result exactly once
  • preserve the existing dynamic-add fallback when the string proof is incomplete

Refs #8410.

Profile

The macOS sample utility hung before collecting a sample on this host, including when reproduced against yes. I used the same symbol-preserving build (PERRY_KEEP_SYMBOLS=1 PERRY_DEBUG_SYMBOLS=1, about 17.7k symbols in the generated fixture) with Instruments Time Profiler over a private 10x iso_miss fixture instead.

Baseline sampled CPU was 8,422 ms. The largest leaves were evalNode (38.90%), js_string_concat_chain (14.15%), lookup (12.19%), memmove (4.19%), arena allocation (3.72%), and the separate accumulator append/storage/rooting envelope (6.80% combined).

Candidate sampled CPU was 7,716 ms (-8.38%). The suffix concat plus separate append envelope becomes one js_string_append_chain leaf (15.15%); evalNode remained dominant (42.69%) and lookup remained essentially unchanged (12.08%).

Performance

Five shuffled, interleaved repeats on macOS, comparing a locally built 8d1cca158 baseline with this branch. Both arms used the identical -p perry -p perry-runtime-static -p perry-stdlib-static release build set, and archive mtimes were verified after each build. Medians are shown.

iso_miss before after delta
wall 3.36 s 2.39 s -28.87%
instructions 12,484,326,208 11,497,214,518 -7.91%
cycles 2,501,750,408 2,267,980,449 -9.34%
peak RSS 32,817,152 B 32,866,304 B +49,152 B (+0.15%)

The wall ranges overlap widely (1.41-5.00 s before, 1.24-7.07 s after), so the wall median is not treated as a real 28.9% result. Instructions retired are the primary signal. The observed RSS cost is 48 KiB; the implementation does not add a cache or retained reserve and allocates the complete result once, but the measured peak is reported rather than rounded away.

Whole-corpus medians:

program wall instructions cycles peak RSS
asyncpipe -27.78% -0.13% -4.31% +0.04%
churn +0.00% -0.05% +2.56% +0.07%
churn_alloc -27.27% -0.08% -2.87% +0.00%
churn_read +0.00% -0.13% -1.21% +0.28%
cycles +0.00% +0.10% +3.90% +0.00%
deeplist +0.00% -0.06% -0.69% +0.03%
fib40 +1.59% -0.03% -0.89% +0.34%
interp +22.22% -0.01% -1.02% +0.05%
iso_miss -28.87% -7.91% -9.34% +0.15%
pipeline +0.00% +0.08% +0.79% -0.07%
push_cls +9.09% -0.02% -2.75% +0.07%
push_num -11.11% -0.15% -5.42% -0.06%
retain -22.22% -0.09% +1.84% +0.01%
retain1 -11.11% -0.05% -2.04% +0.00%
retain_wide +13.51% +0.41% -0.50% +0.00%
retain_wide1 -11.11% -0.20% -1.85% +0.00%
shapes +33.33% -0.03% -2.24% +0.15%
tree -22.73% -0.11% -4.88% -0.06%
tree_wide +21.54% +0.02% -0.41% +0.00%

No non-target row moved more than 0.41% in instructions. All non-target wall ranges overlapped; the large wall/cycle swings track host contention rather than instruction count.

Validation

  • all 19 corpus programs byte-exact against expected output
  • cargo test --release -p perry-runtime --lib: 2,608 passed, 4 ignored
  • cargo test --release -p perry-codegen --lib: 1,121 passed
  • cargo test --release -p perry --bin perry: 1,008 passed
  • lint: initial full run passed 50/52; the two branch-specific ratchets were fixed and pass individually, but the final full 52-gate rerun is blocked by the host disk floor
  • gap suite: interrupted after 25/575 when the documented skip-build path reached a nested HTTP-extension Cargo build; a complete retry is blocked by the host disk floor

Host status at handoff: 6 GiB free after deleting this worktree's generated target/ and reducing the reserved external target to about 832 MiB. The task requires stopping below 15 GiB, so this PR remains draft until those two acceptance runs can complete.

@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5b055ef1-07c8-4680-9f33-100a11fbb9b4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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