Skip to content

Comments

⚡️ Speed up function _contains_jsx by 149% in PR #1562 (codeflash/optimize-pr1561-2026-02-20T03.10.31)#1568

Merged
claude[bot] merged 1 commit intocodeflash/optimize-pr1561-2026-02-20T03.10.31from
codeflash/optimize-pr1562-2026-02-20T03.28.04
Feb 20, 2026
Merged

⚡️ Speed up function _contains_jsx by 149% in PR #1562 (codeflash/optimize-pr1561-2026-02-20T03.10.31)#1568
claude[bot] merged 1 commit intocodeflash/optimize-pr1561-2026-02-20T03.10.31from
codeflash/optimize-pr1562-2026-02-20T03.28.04

Conversation

@codeflash-ai
Copy link
Contributor

@codeflash-ai codeflash-ai bot commented Feb 20, 2026

⚡️ This pull request contains optimizations for PR #1562

If you approve this dependent PR, these changes will be merged into the original PR branch codeflash/optimize-pr1561-2026-02-20T03.10.31.

This PR will be automatically closed if the original PR is merged.


📄 149% (1.49x) speedup for _contains_jsx in codeflash/languages/javascript/frameworks/react/profiler.py

⏱️ Runtime : 539 microseconds 216 microseconds (best of 101 runs)

📝 Explanation and details

The optimized code achieves a 149% speedup (539μs → 216μs) by replacing recursive tree traversal with an iterative stack-based approach.

Key Optimization

Eliminated recursive function calls: The original implementation used any(_contains_jsx(child) for child in node.children), which created a new stack frame for each recursive call. The line profiler shows this consumed 84.1% of total runtime (2.23ms out of 2.65ms). The optimized version uses an explicit stack data structure with a while loop, avoiding Python's function call overhead entirely.

Why This Is Faster

  1. No recursive overhead: Each recursive call in Python involves creating a new stack frame, copying arguments, and managing return values. The iterative approach eliminates all of this.

  2. Early termination efficiency: Both versions can return True early when JSX is found, but the iterative version does this more efficiently without unwinding the call stack.

  3. Better memory locality: The explicit stack keeps all traversal state in a single list object, improving CPU cache utilization compared to scattered stack frames.

Performance Characteristics

The optimization shines particularly well on:

  • Deep nesting: 100-level deep tree shows 691% speedup (94.9μs → 12.0μs)
  • Wide trees with JSX at end: 100 siblings with JSX as last child shows 1985% speedup (34.3μs → 1.64μs)
  • Balanced trees: 512-node tree shows 195% speedup (308μs → 104μs)

Trade-off: Direct JSX matches (root node is JSX) are ~20-26% slower due to stack initialization overhead, but these simple cases are already extremely fast (<1μs) and the optimization dramatically benefits complex real-world AST traversals.

Impact

For React code analysis tools that traverse Abstract Syntax Trees to detect JSX elements, this optimization significantly reduces profiling overhead, especially when analyzing large component files with deeply nested or wide component trees.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 23 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Click to see Generated Regression Tests
import pytest
from codeflash.languages.javascript.frameworks.react.profiler import \
    _contains_jsx
from tree_sitter import Language, Node, Parser

class TestBasicFunctionality:
    """Test basic cases where _contains_jsx behaves as expected."""
    
    def test_jsx_element_direct_match(self):
        """Test that a node with type 'jsx_element' returns True."""
        # Create a minimal mock that satisfies the interface
        class MockNode:
            type = "jsx_element"
            children = []
        
        node = MockNode()
        # Call the function - should return True for jsx_element type
        codeflash_output = _contains_jsx(node); result = codeflash_output # 831ns -> 1.03μs (19.5% slower)
    
    def test_jsx_self_closing_direct_match(self):
        """Test that a node with type 'jsx_self_closing_element' returns True."""
        class MockNode:
            type = "jsx_self_closing_element"
            children = []
        
        node = MockNode()
        codeflash_output = _contains_jsx(node); result = codeflash_output # 691ns -> 942ns (26.6% slower)
    
    def test_jsx_fragment_direct_match(self):
        """Test that a node with type 'jsx_fragment' returns True."""
        class MockNode:
            type = "jsx_fragment"
            children = []
        
        node = MockNode()
        codeflash_output = _contains_jsx(node); result = codeflash_output # 682ns -> 922ns (26.0% slower)
    
    def test_non_jsx_node_no_children(self):
        """Test that a non-JSX node with no children returns False."""
        class MockNode:
            type = "identifier"
            children = []
        
        node = MockNode()
        codeflash_output = _contains_jsx(node); result = codeflash_output # 1.60μs -> 1.18μs (35.6% faster)
    
    def test_jsx_in_single_child(self):
        """Test that JSX in a single child node is detected."""
        class MockNode:
            type = "identifier"
            children = []
        
        class ParentNode:
            type = "expression"
            children = []
        
        # Create JSX child
        jsx_child = MockNode()
        jsx_child.type = "jsx_element"
        jsx_child.children = []
        
        # Create parent with JSX child
        parent = ParentNode()
        parent.children = [jsx_child]
        
        codeflash_output = _contains_jsx(parent); result = codeflash_output # 2.25μs -> 1.31μs (71.7% faster)
    
    def test_non_jsx_in_single_child(self):
        """Test that non-JSX children don't cause false positive."""
        class MockNode:
            type = "identifier"
            children = []
        
        class ParentNode:
            type = "expression"
            children = []
        
        # Create non-JSX child
        non_jsx_child = MockNode()
        non_jsx_child.type = "string"
        non_jsx_child.children = []
        
        # Create parent with non-JSX child
        parent = ParentNode()
        parent.children = [non_jsx_child]
        
        codeflash_output = _contains_jsx(parent); result = codeflash_output # 2.16μs -> 1.43μs (51.0% faster)

class TestEdgeCases:
    """Test edge cases and boundary conditions."""
    
    def test_empty_children_list(self):
        """Test node with explicitly empty children list."""
        class MockNode:
            type = "expression"
            children = []
        
        node = MockNode()
        codeflash_output = _contains_jsx(node); result = codeflash_output # 1.49μs -> 1.18μs (26.1% faster)
    
    def test_deeply_nested_jsx(self):
        """Test JSX nested multiple levels deep."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Create deeply nested structure: parent -> child -> grandchild (JSX)
        grandchild = MockNode()
        grandchild.type = "jsx_element"
        grandchild.children = []
        
        child = MockNode()
        child.type = "block"
        child.children = [grandchild]
        
        parent = MockNode()
        parent.type = "program"
        parent.children = [child]
        
        codeflash_output = _contains_jsx(parent); result = codeflash_output # 2.78μs -> 1.44μs (92.5% faster)
    
    def test_multiple_children_jsx_in_middle(self):
        """Test JSX detection when JSX is in the middle of multiple children."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Create three children: non-JSX, JSX, non-JSX
        child1 = MockNode()
        child1.type = "string"
        child1.children = []
        
        child2 = MockNode()
        child2.type = "jsx_element"
        child2.children = []
        
        child3 = MockNode()
        child3.type = "number"
        child3.children = []
        
        parent = MockNode()
        parent.type = "expression_statement"
        parent.children = [child1, child2, child3]
        
        codeflash_output = _contains_jsx(parent); result = codeflash_output # 2.56μs -> 1.62μs (57.4% faster)
    
    def test_multiple_children_all_non_jsx(self):
        """Test multiple children when none contain JSX."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Create three non-JSX children
        child1 = MockNode()
        child1.type = "string"
        child1.children = []
        
        child2 = MockNode()
        child2.type = "number"
        child2.children = []
        
        child3 = MockNode()
        child3.type = "identifier"
        child3.children = []
        
        parent = MockNode()
        parent.type = "expression"
        parent.children = [child1, child2, child3]
        
        codeflash_output = _contains_jsx(parent); result = codeflash_output # 2.73μs -> 1.97μs (38.1% faster)
    
    def test_all_three_jsx_types_in_siblings(self):
        """Test detection when all three JSX types are siblings."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Create JSX element
        jsx_element = MockNode()
        jsx_element.type = "jsx_element"
        jsx_element.children = []
        
        # Create JSX self-closing element
        jsx_self_closing = MockNode()
        jsx_self_closing.type = "jsx_self_closing_element"
        jsx_self_closing.children = []
        
        # Create JSX fragment
        jsx_fragment = MockNode()
        jsx_fragment.type = "jsx_fragment"
        jsx_fragment.children = []
        
        parent = MockNode()
        parent.type = "program"
        parent.children = [jsx_element, jsx_self_closing, jsx_fragment]
        
        codeflash_output = _contains_jsx(parent); result = codeflash_output # 2.04μs -> 1.27μs (60.6% faster)
    
    def test_case_sensitivity_of_type_names(self):
        """Test that node type names are case-sensitive."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Try uppercase - should not match
        node = MockNode()
        node.type = "JSX_ELEMENT"
        node.children = []
        
        codeflash_output = _contains_jsx(node); result = codeflash_output # 1.28μs -> 1.06μs (20.7% faster)
    
    def test_similar_but_different_type_names(self):
        """Test that similar type names don't cause false positives."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Try similar but different names
        node = MockNode()
        node.type = "jsx_element_invalid"
        node.children = []
        
        codeflash_output = _contains_jsx(node); result = codeflash_output # 1.31μs -> 982ns (33.6% faster)
    
    def test_very_long_type_name(self):
        """Test node with very long type name that doesn't match."""
        class MockNode:
            type = "a" * 1000
            children = []
        
        node = MockNode()
        codeflash_output = _contains_jsx(node); result = codeflash_output # 1.44μs -> 1.19μs (20.9% faster)
    
    def test_special_characters_in_type_name(self):
        """Test that special characters in type name don't cause issues."""
        class MockNode:
            type = "identifier"
            children = []
        
        node = MockNode()
        node.type = "jsx_element\x00"  # Null character
        node.children = []
        
        codeflash_output = _contains_jsx(node); result = codeflash_output # 1.37μs -> 1.03μs (33.0% faster)
    
    def test_generator_evaluated_completely(self):
        """Test that any() generator is evaluated correctly for early termination."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Create parent with first child being JSX
        jsx_child = MockNode()
        jsx_child.type = "jsx_element"
        jsx_child.children = []
        
        # Create a non-JSX child that would be expensive
        non_jsx_child = MockNode()
        non_jsx_child.type = "expensive_node"
        non_jsx_child.children = []
        
        parent = MockNode()
        parent.type = "expression"
        parent.children = [jsx_child, non_jsx_child]
        
        codeflash_output = _contains_jsx(parent); result = codeflash_output # 2.07μs -> 1.77μs (17.0% faster)

class TestLargeScale:
    """Test with larger data structures and multiple iterations."""
    
    def test_deeply_nested_100_levels(self):
        """Test JSX detection in a chain 100 nodes deep."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Build a chain of 99 nodes, with JSX at the end
        current_node = MockNode()
        current_node.type = "jsx_element"
        current_node.children = []
        
        # Wrap it 99 times
        for i in range(99):
            parent = MockNode()
            parent.type = f"level_{i}"
            parent.children = [current_node]
            current_node = parent
        
        codeflash_output = _contains_jsx(current_node); result = codeflash_output # 94.9μs -> 12.0μs (691% faster)
    
    def test_wide_tree_100_siblings_no_jsx(self):
        """Test with 100 sibling nodes, none containing JSX."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Create 100 non-JSX children
        children = []
        for i in range(100):
            child = MockNode()
            child.type = f"child_{i}"
            child.children = []
            children.append(child)
        
        parent = MockNode()
        parent.type = "program"
        parent.children = children
        
        codeflash_output = _contains_jsx(parent); result = codeflash_output # 33.7μs -> 13.0μs (158% faster)
    
    def test_wide_tree_100_siblings_with_jsx_last(self):
        """Test with 100 siblings where JSX is the last child."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Create 99 non-JSX children
        children = []
        for i in range(99):
            child = MockNode()
            child.type = f"child_{i}"
            child.children = []
            children.append(child)
        
        # Add JSX as last child
        jsx_child = MockNode()
        jsx_child.type = "jsx_element"
        jsx_child.children = []
        children.append(jsx_child)
        
        parent = MockNode()
        parent.type = "program"
        parent.children = children
        
        codeflash_output = _contains_jsx(parent); result = codeflash_output # 34.3μs -> 1.64μs (1985% faster)
    
    def test_balanced_tree_512_nodes_no_jsx(self):
        """Test with a balanced binary tree of 512 nodes, no JSX."""
        class MockNode:
            type = "identifier"
            children = []
        
        def create_balanced_tree(depth):
            """Create a balanced binary tree of given depth."""
            if depth == 0:
                node = MockNode()
                node.type = "leaf"
                node.children = []
                return node
            
            node = MockNode()
            node.type = f"level_{depth}"
            node.children = [create_balanced_tree(depth - 1) for _ in range(2)]
            return node
        
        root = create_balanced_tree(9)  # 2^10 - 1 = 1023 nodes, we'll do depth 9 for ~511
        codeflash_output = _contains_jsx(root); result = codeflash_output # 308μs -> 104μs (195% faster)
    
    def test_balanced_tree_512_nodes_with_jsx_at_root(self):
        """Test with balanced tree where root is JSX."""
        class MockNode:
            type = "identifier"
            children = []
        
        def create_balanced_tree(depth):
            """Create a balanced binary tree of given depth."""
            if depth == 0:
                node = MockNode()
                node.type = "leaf"
                node.children = []
                return node
            
            node = MockNode()
            node.type = f"level_{depth}"
            node.children = [create_balanced_tree(depth - 1) for _ in range(2)]
            return node
        
        root = MockNode()
        root.type = "jsx_element"
        root.children = [create_balanced_tree(8) for _ in range(2)]
        
        codeflash_output = _contains_jsx(root); result = codeflash_output # 711ns -> 962ns (26.1% slower)
    
    def test_multiple_jsx_in_large_tree(self):
        """Test large tree with multiple JSX nodes scattered throughout."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Create 10 branches, some with JSX deep inside
        branches = []
        for i in range(10):
            if i % 3 == 0:  # Every third branch has JSX deep inside
                jsx_node = MockNode()
                jsx_node.type = "jsx_element"
                jsx_node.children = []
                
                container = MockNode()
                container.type = "container"
                container.children = [jsx_node]
                branches.append(container)
            else:
                branch = MockNode()
                branch.type = f"branch_{i}"
                branch.children = []
                branches.append(branch)
        
        root = MockNode()
        root.type = "program"
        root.children = branches
        
        codeflash_output = _contains_jsx(root); result = codeflash_output # 2.88μs -> 1.58μs (81.6% faster)
    
    def test_repeated_lookups_consistency(self):
        """Test that repeated lookups on same node return consistent results."""
        class MockNode:
            type = "identifier"
            children = []
        
        jsx_child = MockNode()
        jsx_child.type = "jsx_element"
        jsx_child.children = []
        
        parent = MockNode()
        parent.type = "expression"
        parent.children = [jsx_child]
        
        # Run 100 times - should always get same result
        results = [_contains_jsx(parent) for _ in range(100)]
    
    def test_many_types_with_none_matching(self):
        """Test tree with many different type names, none matching JSX."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Create a tree with many different type names
        leaf_nodes = []
        type_names = [
            "string", "number", "identifier", "binary_expression",
            "call_expression", "member_expression", "array", "object",
            "function_declaration", "class_declaration", "if_statement",
            "while_loop", "for_loop", "return_statement", "variable_declaration",
            "assignment", "regex", "template_string", "spread_element",
            "destructuring_pattern", "arrow_function", "async_function",
        ]
        
        for tname in type_names * 5:  # Repeat to get ~100+ nodes
            node = MockNode()
            node.type = tname
            node.children = []
            leaf_nodes.append(node)
        
        root = MockNode()
        root.type = "program"
        root.children = leaf_nodes
        
        codeflash_output = _contains_jsx(root); result = codeflash_output # 36.7μs -> 14.0μs (162% faster)
    
    def test_recursive_call_limit_check(self):
        """Test that recursion doesn't cause stack issues with deep nesting."""
        class MockNode:
            type = "identifier"
            children = []
        
        # Create 500 levels of nesting - tests recursion depth
        current = MockNode()
        current.type = "identifier"
        current.children = []
        
        for i in range(500):
            parent = MockNode()
            parent.type = f"wrapper_{i}"
            parent.children = [current]
            current = parent
        
        # Should not raise RecursionError
        codeflash_output = _contains_jsx(current); result = codeflash_output
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

To edit these changes git checkout codeflash/optimize-pr1562-2026-02-20T03.28.04 and push.

Codeflash Static Badge

The optimized code achieves a **149% speedup** (539μs → 216μs) by replacing recursive tree traversal with an iterative stack-based approach.

## Key Optimization

**Eliminated recursive function calls**: The original implementation used `any(_contains_jsx(child) for child in node.children)`, which created a new stack frame for each recursive call. The line profiler shows this consumed **84.1% of total runtime** (2.23ms out of 2.65ms). The optimized version uses an explicit stack data structure with a while loop, avoiding Python's function call overhead entirely.

## Why This Is Faster

1. **No recursive overhead**: Each recursive call in Python involves creating a new stack frame, copying arguments, and managing return values. The iterative approach eliminates all of this.

2. **Early termination efficiency**: Both versions can return `True` early when JSX is found, but the iterative version does this more efficiently without unwinding the call stack.

3. **Better memory locality**: The explicit stack keeps all traversal state in a single list object, improving CPU cache utilization compared to scattered stack frames.

## Performance Characteristics

The optimization shines particularly well on:
- **Deep nesting**: 100-level deep tree shows **691% speedup** (94.9μs → 12.0μs)
- **Wide trees with JSX at end**: 100 siblings with JSX as last child shows **1985% speedup** (34.3μs → 1.64μs)  
- **Balanced trees**: 512-node tree shows **195% speedup** (308μs → 104μs)

Trade-off: Direct JSX matches (root node is JSX) are ~20-26% slower due to stack initialization overhead, but these simple cases are already extremely fast (<1μs) and the optimization dramatically benefits complex real-world AST traversals.

## Impact

For React code analysis tools that traverse Abstract Syntax Trees to detect JSX elements, this optimization significantly reduces profiling overhead, especially when analyzing large component files with deeply nested or wide component trees.
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Feb 20, 2026
@claude
Copy link
Contributor

claude bot commented Feb 20, 2026

PR Review Summary

Prek Checks

✅ All checks passed — no formatting or linting issues found.

Mypy

✅ No type errors in the changed file.

Code Review

✅ No critical issues found.

The change converts _contains_jsx from a recursive implementation to an iterative stack-based approach. The logic is equivalent:

  • Both check if node.type is one of the three JSX types
  • Both traverse all children if no match is found
  • The iterative version avoids Python function call overhead for deep/wide trees

This is a safe, behavior-preserving optimization.

Test Coverage

File Coverage Status
codeflash/languages/javascript/frameworks/react/profiler.py 0% ⚠️ No coverage

Note: This file does not exist on main — it was introduced in the base branch (codeflash/optimize-pr1561-2026-02-20T03.10.31), not by this PR. This PR only modifies the _contains_jsx function implementation. The 0% coverage is a pre-existing condition from the parent branch and is not a regression introduced by this change.

Overall project coverage: 78% (unchanged by this PR).


Last updated: 2026-02-20

@claude claude bot merged commit ae71d41 into codeflash/optimize-pr1561-2026-02-20T03.10.31 Feb 20, 2026
22 of 27 checks passed
@claude claude bot deleted the codeflash/optimize-pr1562-2026-02-20T03.28.04 branch February 20, 2026 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants