Skip to content

Dedup ImportVar entries in merge_imports / merge_parsed_imports#6737

Open
Alek99 wants to merge 4 commits into
mainfrom
claude/reflex-compiler-perf-t8ztc9-12-merge-imports-dedup
Open

Dedup ImportVar entries in merge_imports / merge_parsed_imports#6737
Alek99 wants to merge 4 commits into
mainfrom
claude/reflex-compiler-perf-t8ztc9-12-merge-imports-dedup

Conversation

@Alek99

@Alek99 Alek99 commented Jul 10, 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 (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

merge_imports (and merge_parsed_imports) extended per-lib lists without dedup. Every @var_operation merges the same operand VarData through both _args and _return (CustomVarOperation._cached_get_all_var_data), so chained operations — rx.cond chains, arithmetic like a + 1 + 1 + … — doubled the merged import-entry count per nesting level:

  • depth 15 → ~196k entries, 29 ms per merge
  • depth 18 → ~1.57M entries, 252 ms per merge

Fix

ImportVar is a frozen (hashable) dataclass. Both merge functions now accumulate per-lib insertion-ordered dicts (dict[ImportVar, None]), which:

  • drops exact duplicates, keeping first-seen order (previously duplicates were only removed downstream by collapse_imports, via an unordered set);
  • preserves entries that differ in any field (alias, is_default, package_path, …);
  • keeps merged VarData constant-sized for chained var operations and linear for component trees.

Return type/shape is unchanged (defaultdict[str, list[ImportVar]], empty-lib keys preserved).

Verification

  • New unit tests: dedup with order preservation in both merge functions; a depth-18 chained-arithmetic regression test asserting the merged VarData import entries stay collapsed (pre-fix this blows up to ~1.57M entries).
  • CodSpeed benchmarks on this PR (test_get_all_imports, test_collect_imports, test_compile_page*) measure the compile-path effect directly.

Note: this session's sandbox has no PyPI egress, so local profiling numbers could not be produced here; the CodSpeed instrumentation run on this PR is the authoritative before/after CPU measurement.

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

🤖 Generated with Claude Code

https://claude.ai/code/session_01Jy8uHH11KircGa2MbTrR8g


Generated by Claude Code

merge_imports extended per-lib lists without dedup. Every
@var_operation merges the same operand VarData through both _args and
_return, so chained operations (rx.cond chains, arithmetic) doubled
the merged import entries per nesting level: depth 15 produced ~196k
entries (29ms per merge), depth 18 ~1.57M (252ms).

ImportVar is a frozen (hashable) dataclass, so both merge functions now
accumulate per-lib insertion-ordered dicts, dropping exact duplicates
while preserving first-seen order and the distinctness of entries that
differ in alias/default/etc. This keeps merged VarData constant-sized
for chained operations and linear for component trees.

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 10, 2026 19:50
@greptile-apps

greptile-apps Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reduces duplicate import entries during var-data import merging. The main changes are:

  • merge_imports now deduplicates exact ImportVar entries while keeping first-seen order.
  • merge_parsed_imports remains a concatenating merge path.
  • Unit tests cover deduplication, distinct import fields, and bounded chained var operations.
  • A performance news entry documents the import-entry growth improvement.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
packages/reflex-base/src/reflex_base/utils/imports.py merge_imports now deduplicates exact ImportVar entries and returns the same parsed-import shape.
tests/units/utils/test_imports.py Tests now cover import deduplication, field-sensitive import preservation, and concatenating parsed-import merges.
tests/units/vars/test_base.py A var-operation test now checks that deeply chained imports stay bounded.
packages/reflex-base/news/6737.performance.md The news entry describes the import deduplication performance improvement.

Reviews (3): Last reviewed commit: "Type the chained-ops regression test via..." | Re-trigger Greptile

@codspeed-hq

codspeed-hq Bot commented Jul 10, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing claude/reflex-compiler-perf-t8ztc9-12-merge-imports-dedup (b968b30) 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.

CodSpeed flagged test_get_all_imports regressing ~40% with dedup in the
component-tree fold: per-entry Python-level hashing outweighs list
extend there, duplication is only linear, and the result is collapsed
downstream anyway. The compounding-duplication path (VarData.merge for
chained var operations) goes through merge_imports, which keeps the
dedup.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jy8uHH11KircGa2MbTrR8g
@linear-code

linear-code Bot commented Jul 10, 2026

Copy link
Copy Markdown

ENG-10102

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