⚡️ Speed up function _node_contains_jsx by 685% in PR #1561 (add/support_react)#1578
Merged
claude[bot] merged 2 commits intoadd/support_reactfrom Feb 20, 2026
Merged
Conversation
The optimized code achieves a **684% speedup** (from 1.03ms to 131μs) by replacing recursive calls with an iterative stack-based approach and using a frozenset for type checking. ## Key Optimizations **1. Eliminated Recursive Overhead** The original code uses recursion with multiple call sites, creating significant overhead from: - Function call stack frames for each node traversal - Generator expression overhead in `any(_node_contains_jsx(child) for child in node.children)` - Repeated function entry/exit costs The optimized version uses an explicit stack with a while loop, eliminating all recursion overhead. This is particularly impactful for tree traversal where every node would trigger a new function call in the original version. **2. Frozenset Lookup for Type Checking** Moving JSX type checks into a `frozenset` (`_JSX_TYPES`) provides O(1) average-case lookup instead of tuple membership testing, which is O(n) linear scan. While the performance difference is small for 5 types, frozensets are optimized for membership testing and signal intent clearly. **3. Simplified Control Flow** The original code had special-case handling for `return_statement` nodes before the generic child traversal. The optimized version treats all nodes uniformly—checking the type first, then processing children—reducing branching and making the code path more predictable. ## Performance Impact by Test Case The optimization excels on **breadth-heavy trees**: - `test_large_breadth_many_children_with_one_jsx_at_end`: **7541% faster** (324μs → 4.25μs) - `test_large_breadth_many_children_no_jsx`: **292% faster** (338μs → 86.5μs) For these cases, the original recursive approach with generator expressions incurs massive overhead when traversing 1000 siblings, while the iterative approach efficiently processes them with minimal per-node cost. For simple cases with few nodes, the speedup is more modest (47-99% faster) due to lower recursion depth, though there is a slight regression (~1-25% slower) for the absolute simplest cases with a single node, likely due to the stack initialization overhead. This is an acceptable trade-off given the dramatic improvements on realistic tree structures. The optimization preserves all behavior including the `TypeError` when `children` is `None`, ensuring backward compatibility.
Contributor
PR Review SummaryPrek Checks✅ Passed — Mypy✅ No issues found in Code Review✅ No critical issues found. This is a clean optimization of
Note: Test Coverage
Summary: New React framework files have good coverage (88-100%) except Last updated: 2026-02-20 |
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.
⚡️ This pull request contains optimizations for PR #1561
If you approve this dependent PR, these changes will be merged into the original PR branch
add/support_react.📄 685% (6.85x) speedup for
_node_contains_jsxincodeflash/languages/javascript/frameworks/react/discovery.py⏱️ Runtime :
1.03 milliseconds→131 microseconds(best of16runs)📝 Explanation and details
The optimized code achieves a 684% speedup (from 1.03ms to 131μs) by replacing recursive calls with an iterative stack-based approach and using a frozenset for type checking.
Key Optimizations
1. Eliminated Recursive Overhead
The original code uses recursion with multiple call sites, creating significant overhead from:
any(_node_contains_jsx(child) for child in node.children)The optimized version uses an explicit stack with a while loop, eliminating all recursion overhead. This is particularly impactful for tree traversal where every node would trigger a new function call in the original version.
2. Frozenset Lookup for Type Checking
Moving JSX type checks into a
frozenset(_JSX_TYPES) provides O(1) average-case lookup instead of tuple membership testing, which is O(n) linear scan. While the performance difference is small for 5 types, frozensets are optimized for membership testing and signal intent clearly.3. Simplified Control Flow
The original code had special-case handling for
return_statementnodes before the generic child traversal. The optimized version treats all nodes uniformly—checking the type first, then processing children—reducing branching and making the code path more predictable.Performance Impact by Test Case
The optimization excels on breadth-heavy trees:
test_large_breadth_many_children_with_one_jsx_at_end: 7541% faster (324μs → 4.25μs)test_large_breadth_many_children_no_jsx: 292% faster (338μs → 86.5μs)For these cases, the original recursive approach with generator expressions incurs massive overhead when traversing 1000 siblings, while the iterative approach efficiently processes them with minimal per-node cost.
For simple cases with few nodes, the speedup is more modest (47-99% faster) due to lower recursion depth, though there is a slight regression (~1-25% slower) for the absolute simplest cases with a single node, likely due to the stack initialization overhead. This is an acceptable trade-off given the dramatic improvements on realistic tree structures.
The optimization preserves all behavior including the
TypeErrorwhenchildrenisNone, ensuring backward compatibility.✅ Correctness verification report:
🌀 Click to see Generated Regression Tests
To edit these changes
git checkout codeflash/optimize-pr1561-2026-02-20T05.27.21and push.