Skip to content

Bypass f-string tag round-trip for var operation operands#6747

Open
Alek99 wants to merge 2 commits into
mainfrom
claude/reflex-compiler-perf-t8ztc9-14-format-tag-bypass
Open

Bypass f-string tag round-trip for var operation operands#6747
Alek99 wants to merge 2 commits into
mainfrom
claude/reflex-compiler-perf-t8ztc9-14-format-tag-bypass

Conversation

@Alek99

@Alek99 Alek99 commented Jul 11, 2026

Copy link
Copy Markdown
Member

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

  • Performance improvement + memory-leak fix (non-breaking change, identical rendered output)

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?

What this does

Interpolating a Var into an f-string (Var.__format__) hashes the var, permanently registers it in the module-global _global_vars dict (which never evicts — a real memory leak, worst under dev hot-reload since entries and their GLOBAL_CACHE values survive GC), and emits a <reflex-var> tag that the constructed expression's __post_init__ then regex-decodes back out. Profiling showed this round-trip is ~30–40% of var-operation construction — and every @var_operation (all arithmetic, comparisons, string/array/object ops) pays it for each operand.

Fix

Operand VarData already reaches the operation through CustomVarOperation._args, so the tag round-trip is pure overhead for operands. var_operation now suppresses tagging on its operand vars while the body runs:

  • the suppression is a ref-counted instance-dict flag, so a nested operation on the same var can't clear an outer suppression early, and it's always removed in a finally;
  • vars created inside an operation body are not operands and still tag normally, so their VarData keeps flowing through the return expression (covered by a dedicated test);
  • formatting outside an operation is unchanged.

Net effect: constructing a + b no longer hashes/registers/regex-decodes its operands, and internal ops no longer grow _global_vars.

Verification

  • New unit tests: _global_vars does not grow when constructing an operation while operand VarData still reaches the merged result; the suppression flag does not persist after the op; body-created vars keep contributing VarData; formatting outside an operation still registers/tags as before.
  • CodSpeed instrumentation on this PR is the authoritative before/after CPU measurement (this sandbox has no PyPI egress for local profiling); numbers will be posted in this description once the run completes — the affected path is exercised by test_console_log, test_evaluate_page*, and all test_compile_* benchmarks.

Part of a compiler-performance series; tracked in Linear as ENG-10104.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Jy8uHH11KircGa2MbTrR8g


Generated by Claude Code

Interpolating a var into an f-string hashes it, permanently registers
it in the module-global _global_vars dict (which never evicts - a
memory leak, worst under dev hot-reload), and emits a tag that the
return expression's __post_init__ regex-decodes back out. For operands
of a @var_operation this round-trip is pure overhead (~30-40% of op
construction): the operation merges operand VarData directly from
_args.

var_operation now suppresses tagging on its operands (ref-counted, so
nested operations on the same var can't clear an outer suppression
early) while the body runs. Vars created inside the body still tag
normally, so their VarData keeps flowing through the return
expression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jy8uHH11KircGa2MbTrR8g
@Alek99 Alek99 requested a review from a team as a code owner July 11, 2026 02:24
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jy8uHH11KircGa2MbTrR8g
@greptile-apps

greptile-apps Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR bypasses f-string tags for operation operands to reduce construction cost and global cache growth. The main changes are:

  • Adds temporary, reference-counted tag suppression to var_operation operands.
  • Preserves operand metadata through CustomVarOperation._args.
  • Adds tests for metadata flow, cleanup, body-created vars, and normal formatting.
  • Documents the performance improvement in a news fragment.

Confidence Score: 4/5

Nested operations can render incomplete JavaScript, and shared suppression state can drop metadata during concurrent formatting.

  • Simple operand metadata flow and cleanup are covered by tests.
  • Nested operation results render through __str__, but the new shortcut reads their empty _js_expr directly.
  • The suppression counter is visible to every caller sharing the same operand instance.

packages/reflex-base/src/reflex_base/vars/base.py and tests/units/vars/test_base.py

Important Files Changed

Filename Overview
packages/reflex-base/src/reflex_base/vars/base.py Adds operand tag suppression, but nested operation rendering and concurrent reuse of shared operands can produce incorrect output or metadata.
tests/units/vars/test_base.py Adds focused tests for simple operands and metadata flow, but does not cover nested operations or concurrent formatting.
packages/reflex-base/news/6747.performance.md Adds a news fragment describing the operation-construction optimization.

Reviews (1): Last reviewed commit: "Add news fragment for var operation tag ..." | Re-trigger Greptile

Comment on lines +847 to +848
if self.__dict__.get("_format_without_tagging"):
return self._js_expr

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Nested Operation Expression Disappears

When an operation result is used as another operation's operand, such as (a + b) * c, the operand is a CustomVarOperation whose _js_expr is empty and whose __str__ renders the actual expression. This branch returns the empty field directly, so the outer operation can emit incomplete JavaScript instead of the nested expression.

Suggested change
if self.__dict__.get("_format_without_tagging"):
return self._js_expr
if self.__dict__.get("_format_without_tagging"):
return str(self)

Comment on lines +1874 to +1878
for operand in operands:
operand_dict = operand.__dict__
operand_dict["_format_without_tagging"] = (
operand_dict.get("_format_without_tagging", 0) + 1
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Shared Suppression Leaks Across Calls

The suppression counter is stored on the shared operand instance. If the same Var is formatted concurrently while an operation body is running, that unrelated formatting also skips tagging, so its enclosing expression can lose the operand's VarData, including required imports or hooks.

@codspeed-hq

codspeed-hq Bot commented Jul 11, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing claude/reflex-compiler-perf-t8ztc9-14-format-tag-bypass (c3f3c22) with main (9a5c4d3)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b4893e8bd

ℹ️ 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".

Comment on lines +847 to +848
if self.__dict__.get("_format_without_tagging"):
return self._js_expr

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve tags when operands feed string Var builders

Because this flag is checked by every Var.__format__ call while a custom var_operation body runs, operands no longer produce the tagged f-string form that LiteralStringVar.create/Var.create depend on to turn f"prefix {value}" into a JS string concat. In that scenario the operand now formats as raw state.name, so the string builder compiles a literal like "prefix state.name" instead of a value depending on state.name; the _args merge only preserves VarData, not the string-concat semantics. Consider limiting the bypass to the var_operation_return JS-expression path rather than the whole body.

Useful? React with 👍 / 👎.

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