Skip to content

perf: recover the Oct 12-19 fixed-cost drift (0286) - #617

Merged
rmorozov merged 1 commit into
masterfrom
claude/project-thread-9gxxka
Oct 23, 2026
Merged

rmorozov merged 1 commit into
masterfrom
claude/project-thread-9gxxka

Conversation

@rmorozov

@rmorozov rmorozov commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Requested by Ruslan · project thread

Problem

The 2026-10-19 scout (task 0286) found a week of fixed-cost drift since 8f13350 (0158). Each feature merge stayed under the +3% gate. Together they moved Render/strings +8.4%, plain_text +4.1%, for_range +3.2%, substitute +3.0%, and expressions, macros and mitsuhiko_table about +1.8%. Load went up +1.3..2.9% on five cases.

What changed

I diffed each suspect merge with callgrind against its first parent (#545, #558, #606, trains 26 and 27), as 0205 did, and fixed the inlining and copy costs these merges added in passing. Every fix is behaviour-neutral.

  • src/testers.cpp: the number-visitor fallback of IsInEqual is out of line. The int fast path of x in [...] no longer pays a frame the BigInt arms enlarged.
  • src/filters.cpp: map() reads its filter's argument error once per call instead of copying it for every item. It still raises at the first item, and not at all for an empty list.
  • src/expression_evaluator.cpp: the markup join of ~ (0051) is its own function. Plain concatenation inlines into BinaryExpression::Apply again.
  • src/global_functions.cpp: range() looks each argument up once.
  • src/template_parser.h: FindKeyword is forced inline into the lexer callback again.
  • docs/tasks/0286: done, with the measured results and the accepted remainder, each item with its Ir and the feature it pays for.

Results

bench/count.py, Release GCC 13, all builds running today's cases:

Case 8f13350 master this PR vs master
Render/expressions 445,855 +1.89% -4.55% -6.33%
Render/strings 584,377 +8.42% +5.58% -2.62%
Render/many_tags 723,649 +1.26% -0.06% -1.31%
Render/for_range 38,030 +3.17% +2.39% -0.75%
Render/macros 637,225 +1.80% +1.29% -0.49%
Load/plain_text 3,672 +2.29% +1.93% -0.35%

No case is worse than master. The chat_mistral allocation step (360 to 448) compared two different versions of the case. Like for like, 8f13350 makes 450 allocations and master 428.

Remaining limits

What is left against 8f13350 is the price of features, listed in the task file:

  • per-render self name, EvalContext, cycle collector and autoescape selector: +40 Ir per render
  • the loop.cycle position cell: +2 Ir per item, plus +21 Ir per loop on recycle
  • namespace dicts with non-string keys (0036)
  • ordered ValuesMap lookups (0043)
  • tester argument parsing at Load (0200)
  • lexer inlining shifts

Load drift is recovered separately by #612 and #616, so the remainder against 8f13350 should be re-measured after those land (perf track note).

Validation

  • Debug build: full ctest passes (5/5).
  • scripts/preflight.sh --perf: clang-format, clang-tidy 22.1.8 on changed lines, null comparisons, the CodeQL pattern, task files and the +3% instruction gate all pass.
  • Verifier: 1 round, ready, no blocking findings.
    • It ran a clang address+undefined build: 6211 tests passed with no sanitizer reports.
    • Its Python Jinja2 probes of map() argument errors, range() and ~ match.
  • CI: all 41 checks green on f9b05c4, including MSVC, Apple Clang and "instruction counts vs base".
  • Perf track: approved from the CI instruction-count job, no exceptions.

Roles: main session (attribution and fixes), verifier (1 round). Red CI pushes: 0.
Codex: 0 findings, 0 fixed, 0 declined (code review on f9b05c4). The security review was requested but Codex did not start it.


Generated by Claude Code

🤖 Generated with Claude Code

https://claude.ai/code/session_016vJUPZkx4gkbvj2T5VCJwE

Callgrind diffs of each merge since 8f13350 against its first parent found
inlining and copy costs the feature merges added in passing:

- IsInEqual's number-visitor fallback is out of line, so the int fast path of
  `x in [...]` needs no frame (Render/expressions -6.3%)
- map() reads its filter's argument error once per call, not per item
- the markup join of `~` is its own function, so the plain concatenation
  inlines into BinaryExpression::Apply again (Render/strings -2.6%)
- range() looks each argument up once
- FindKeyword is forced inline into the lexer callback again

No case is worse than master. The remainder against 8f13350, each the
price of a feature, is listed with its Ir in docs/tasks/0286.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016vJUPZkx4gkbvj2T5VCJwE
@rmorozov rmorozov self-assigned this Oct 23, 2026

Copy link
Copy Markdown
Member Author

@codex review

@codex security review


Generated by Claude Code

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-23T14:16:32.105021Z f9b05c4 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: f9b05c4515

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@rmorozov
rmorozov marked this pull request as ready for review October 23, 2026 14:17
@rmorozov
rmorozov merged commit caaf1c1 into master Oct 23, 2026
41 checks passed
rmorozov added a commit that referenced this pull request Oct 23, 2026
…oescape, ConfinedFileSystem, fixed-cost recovery (#619)

Merge train 30: error locations and codes (#612), big integers (#613), volatile autoescape (#614), ConfinedFileSystem (#615), fixed-cost recovery (#617)
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