Repository navigation
perf: template root and raw text own nothing; lighter parse scaffolding (0118 P5b-2) - #437
Merged
Merged
Conversation
…template (0118 P5b-2a) TemplateRenderer's block map becomes an ArenaSpan of BlockStatement refs, filled at the end of the parse from a parser-side TemplateRootInfo, and RawTextRenderer drops its shared_ptr holder: text converted to newline_sequence lives in a template-owned list. Both nodes now own nothing, so Seal neither relocates nor destroys them through hooks. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QT4pkibQA9uD34K5vYkC2j
The stack of open statements is a small_vector of four instead of a std::list, so the root costs no allocation, and the arena's inline block and offset list are left uninitialized instead of zero-filled: Seal reads only the bytes and offsets made. Load plain_text -6.5%, substitute -2.1%. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QT4pkibQA9uD34K5vYkC2j
rmorozov
marked this pull request as ready for review
October 8, 2026 06:32
rmorozov
pushed a commit
that referenced
this pull request
Oct 8, 2026
…e cache) Filed from the 0118 P5b and 0117 P2 reviews. Also adds the missing index rows for 0145 and 0146 and closes 0146 (option 2 merged in #435; the perf track no longer needs option 1 since #437 brought plain_text under target). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M4RSuk9cfqu9jdeaWMRDKW
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.
🤖 Generated with Claude Code
https://claude.ai/code/session_01QT4pkibQA9uD34K5vYkC2j
Before: a template's root node keeps its blocks in an
unordered_map. A raw text node holds ashared_ptrto its text whenevernewline_sequencechanges the text. Every Load also allocates astd::listnode for the statement stack and zero-fills the arena's 512-byte inline block.After: the root and raw text nodes own nothing, so the arena neither destroys them nor relocates them through a hook. The statement stack and the arena scaffolding cost no allocation or fill. Rendering is unchanged. Load plain_text drops from 4,320 to 4,038 instructions, below the wave 2 target of 4,121.
How (two commits):
TemplateRendererkeeps its blocks as anArenaSpan<NodeRef<BlockStatement>>. The parser collects them inTemplateRootInfoand sets the span when the parse ends.std::unordered_set<std::string_view>beyond that. The verifier found the linear-only version quadratic on hostile templates: 100k blocks took 51 s.newline_sequencelives in astd::forward_listthat the template owns next to its source.static_assertlist of trivially destructible nodes.StatementInfoListis aboost::container::small_vector<StatementInfo, 4>instead ofstd::list. The verifier audited all users: none holds a reference across a push.NodeArena's inline block andOffsetList's inline array are no longer zero-filled. Seal reads only the bytes and offsets that were made; valgrind memcheck is clean.BasicTests.NewlineSequenceTextOutlivesParse(narrow and wide, inside a block, rendered twice).BasicTests.ManyBlocksRejectADuplicateName(40 blocks, duplicates at positions 3 and 39).Numbers (bench/count.py, Release, NODEREF_CHECKS=ON)
Load against the 0892811 targets:
Process
\r\nand\rshowed 0 differences, and about 400k ASan fuzz iterations were clean.Generated by Claude Code