Skip to content

Read a constant left operand in place: no shared count bump per render (0149) - #474

Merged
rmorozov merged 2 commits into
masterfrom
claude/static-constants-0149-nrry3o
Oct 11, 2026
Merged

rmorozov merged 2 commits into
masterfrom
claude/static-constants-0149-nrry3o

Conversation

@rmorozov

Copy link
Copy Markdown
Member

Requested by Ruslan · project thread

Before: in '<|start_header_id|>' + message['role'], the long-string constant on the left was copied on every evaluation because the right operand is not "pure". Each copy is an atomic increment and decrement on the constant's count, which every thread rendering the template shares. In a chat-style loop that count is contended: 4 threads rendered only 1.5x as fast as 1.

After: a ConstantExpression on the left is always read in place, because evaluating the right operand cannot change it. Nothing is borrowed beyond the expression, so no value can escape the template. The same loop now scales 3.6x on 4 threads (24k to 42k renders/s).

How: BinaryExpression's constructor sets m_leftByRef when the left node is a ConstantExpression, as well as when both operands are pure (src/expression_evaluator.cpp:469). I added six rows to ConstantSubstitutionTest with a constant left operand and an impure right one; they match Python Jinja2.

Not built: the static heap kind 0149 proposed. I measured it as a flag on ValueObject that intrusive_ptr_add_ref/release skip. It cost Render +0.3..+1.4% Ir on every case and gave no measurable MT gain on the suite. The suite copies at most 18 constants per render, and those copies come from 3 sites. The numbers, the sites and a reopen condition are in docs/tasks/0149 (status: done). The remaining constant copies are stores, such as list-literal items and macro arguments, and they must own what they hold.

Counts vs 5ce1786 (local count.py):

  • Render: chat_llama -0.13%, chat_mistral -0.09%, chat_qwen -0.11%, html_autoescape -0.18%; every other case ±0.00%.
  • Load: +0.00..+0.35%. The largest is expressions (+156 Ir), from one kind check per binary operator.

Roles: one verifier round with ASan+UBSan, the full suite and 102 templates compared with Python. It found no blocking issues, and its one nit (the comment wording) is fixed. Pushes red in CI: 0 so far.

The one mismatch it found, ~ with a Markup right operand under autoescape, is the same on base and already tracked as autoescape.env_on_concat_markup_var (0051).

Touches src/expression_evaluator.{h,cpp} (the comment and ctor lines only). 0158 is changing expression_evaluator.h in parallel; git merge-tree will be checked before merge.

🤖 Generated with Claude Code

https://claude.ai/code/session_0141uuEzTYXvK4MHDi355Cgn


Generated by Claude Code

BinaryExpression read its left operand by reference only when the right one was
pure, which also held back constants: `'<|start_header_id|>' + m['role']` copied
the long-string constant, an atomic increment on the count every concurrent
render of the template shares. A constant cannot change while the right operand
is evaluated, so it is now always read in place. A chat-style loop of 200 such
concatenations goes from 24k to 42k renders/s at 4 threads.

The static heap kind 0149 proposed was measured and not built: a flag check in
intrusive_ptr_add_ref/release costs Render +0.3..+1.4% Ir on every case and
shows no MT gain on the suite. Numbers in docs/tasks/0149.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141uuEzTYXvK4MHDi355Cgn
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141uuEzTYXvK4MHDi355Cgn
@rmorozov rmorozov self-assigned this Oct 11, 2026
@rmorozov
rmorozov marked this pull request as ready for review October 11, 2026 23:40
@rmorozov
rmorozov merged commit 320c725 into master Oct 11, 2026
38 checks passed
rmorozov pushed a commit that referenced this pull request Oct 11, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KMcWcpGwhiaEs33YjAgEV4
rmorozov added a commit that referenced this pull request Oct 11, 2026
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.

2 participants