Repository navigation
Load: halve the cost of loading tag-heavy templates (0103) - #377
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SGHFyqdC8NgXXsL6PatsQP
…per rough split Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SGHFyqdC8NgXXsL6PatsQP
Quoted keywords ('in', 'if', 'not', ...) are strings, never keywords, as in
Python Jinja2; the errors corpus now covers that.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SGHFyqdC8NgXXsL6PatsQP
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SGHFyqdC8NgXXsL6PatsQP
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SGHFyqdC8NgXXsL6PatsQP
…ad-wu2i55 # Conflicts: # docs/tasks/README.md
MSVC (C++17, C3493) refuses to use a non-static local constexpr inside a capture-less lambda without capturing it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SGHFyqdC8NgXXsL6PatsQP
rmorozov
marked this pull request as ready for review
October 4, 2026 03:28
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.
Requested by Ruslan · project thread
Before: loading
Load/many_tagstook 44.15M instructions and 34,249 allocations. Most of that was the parser looking up keywords again at every precedence level for every token, copying tokens and parse results level by level, and copyingSettingsfor every statement tag.After: the same load takes 21.99M instructions (2.01x cheaper) and 16,559 allocations (-52%). Every other
Load/case is 31-51% cheaper, andRender/is unchanged. Rendered output and error messages are byte-identical to master, with one exception that now matches Python (below).How:
Token::keyword; the parsers read it instead of callingGetKeyword.FindKeywordindexes by first character.LexBuffers), and tokens are built in place.ParseUnaryPlusMinuscalls the postfix and filter parsers only when the next token can start them, and token copies became references.StatementsParserholdsconst Settings&instead of a copy; statement infos are moved, not copied.MarkMacroSpecialNamesreturns at once outside macros, attribute subscripts no longer allocate a constant node,IsMethodNamebinary-searches,FindBlockEndskips plain characters,MatchTagAtgates raw/meta on the first letter.Deliberate behaviour change (parity fix): a quoted keyword such as
'in'or'if'used to be treated as the keyword, becauseGetKeywordread the token's source text. It is now a string, as in Python Jinja2, so{{ 1 'in' l }}is a syntax error and{% for a in l, 'if' %}renders. New cases intest/parity/cases/errors.pypin it.bench/count.py --baseline(master before → this branch)Render/cases are all within -3.6%..+0.0% (no render code changed;for_loop_vars-3.6% comes from cheaper attribute subscripts).Tasks
make_shared) was wrong; the profile showed keyword lookups and copies.FullExpressionEvaluatorwrapper, filter creation, string constant copies, the lexer itself, template destruction,expectedchurn andmalloc_consolidate(reserving buffers madelarge_static26% slower, so it was left out). First filed as 0107, renumbered after Split StringConverter::Filter into one member per mode (0061) #370 took 0107 (0108 is taken by perf: resolve include/extends/import targets once per render, with a Jinja2-exact option (0105) #376).Process
IsEqualon attribute subscripts compares nullexprpointers (no practical effect); possible MSVC C4996 on 4-argumentstd::equal; clang-tidy 22 not run locally (CI checks it).docs/tasks/README.mdconflict from the renumbering, and again (a774747) before reporting final to the merge steward; tests pass on both merges.constexpr(charsCountinFindKeyword) used inside a capture-less lambda, which GCC, Clang and MSVC C++20 accept. Fixed by making itstatic constexpr(f770c6f).🤖 Generated with Claude Code
https://claude.ai/code/session_01SGHFyqdC8NgXXsL6PatsQP