Engine: Single-pass optimize_tokens - #2232
Merged
marcoroth merged 2 commits intoAug 15, 2026
Merged
Conversation
Collapse the two-pass whitespace/text optimization in Herb::Engine::Compiler into a single pass over the raw token stream.
joelhawksley
marked this pull request as ready for review
August 14, 2026 17:20
marcoroth
reviewed
Aug 15, 2026
marcoroth
reviewed
Aug 15, 2026
marcoroth
reviewed
Aug 15, 2026
marcoroth
reviewed
Aug 15, 2026
Co-authored-by: Marco Roth <marco.roth@intergga.ch> Signed-off-by: Marco Roth <marco.roth@intergga.ch>
marcoroth
approved these changes
Aug 15, 2026
marcoroth
left a comment
Owner
There was a problem hiding this comment.
Nice, small change, big win!
Thank you @joelhawksley! 🙏🏼
marcoroth
enabled auto-merge (squash)
August 15, 2026 00:41
marcoroth
disabled auto-merge
August 15, 2026 00:41
marcoroth
enabled auto-merge (squash)
August 15, 2026 00:42
optimize_tokens
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Collapses the two-pass whitespace/text optimization in
Herb::Engine::Compiler#optimize_tokensinto a single pass over the raw token stream.Previously
optimize_tokensdid two passes:compact_whitespace_tokensbuilt a whole intermediate array (tokens.map.with_index { ... }.compact), dropping/relabeling whitespace tokens.optimize_tokensre-scanned that array to merge consecutive text tokens, accumulating withcurrent_text += value.This PR folds both into one pass: whitespace tokens are resolved against their neighbours in the original stream (dropped, or turned into text) and consecutive text is merged inline.
compact_whitespace_tokensis removed.optimize_tokensruns once per template compile, so this is on the hot path for any largeActionView/ReActionView precompile.Implementation notes
map.with_index + compactallocation is gone; the surviving whitespace-vs-neighbour checks (adjacent_whitespace?,whitespace_before_code_sequence?) run against the originaltokens/index, exactly as before.current_text << valueinstead ofcurrent_text += value, which reallocated and copied the whole accumulated string on every text token.value.dupso a (possibly frozen) token value is never mutated in place.Benchmark
Measured end-to-end through
ViewPrecompiler.precompileover the github/github monolith template corpus (6,302 templates), ReActionView ON (Herb path), Ruby 4.0.5.Both sides were run against the same Herb
mainnative extension — onlylib/herb/engine/compiler.rbdiffers between them — so the delta isolates this change. 2 boots × 5 timed iterations each.mainbaselineThe stable, reproducible win is ~1.06M fewer allocated objects per full precompile (−3.3%). Wall-clock is consistently favorable but smaller and noisier (~1–3%).
Benchmark run by Claude Opus 4.8 (GitHub Copilot), acting on behalf of @joelhawksley.
Correctness
Output is behavior-preserving — the full Herb engine test suite passes unchanged (1,139 runs, 3,811 assertions, 0 failures, 0 errors), RuboCop is clean, and
sig/herb/engine/compiler.rbsis regenerated viarbs-inline.Split out of #1872.