Skip to content

Comments

⚡️ Speed up method ExpectCallTransformer.transform by 173% in PR #1523 (feat/js-dot-call-instrumentation)#1527

Merged
mohammedahmed18 merged 1 commit intofeat/js-dot-call-instrumentationfrom
codeflash/optimize-pr1523-2026-02-18T13.29.34
Feb 18, 2026
Merged

⚡️ Speed up method ExpectCallTransformer.transform by 173% in PR #1523 (feat/js-dot-call-instrumentation)#1527
mohammedahmed18 merged 1 commit intofeat/js-dot-call-instrumentationfrom
codeflash/optimize-pr1523-2026-02-18T13.29.34

Conversation

@codeflash-ai
Copy link
Contributor

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

⚡️ This pull request contains optimizations for PR #1523

If you approve this dependent PR, these changes will be merged into the original PR branch feat/js-dot-call-instrumentation.

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


📄 173% (1.73x) speedup for ExpectCallTransformer.transform in codeflash/languages/javascript/instrument.py

⏱️ Runtime : 85.2 milliseconds 31.3 milliseconds (best of 65 runs)

📝 Explanation and details

The optimized code achieves a 172% speedup (85.2ms → 31.3ms) by eliminating a critical O(n²) performance bottleneck in the transform() method.

Key Optimization

Problem: The original code called is_inside_string(code, match.start()) for every regex match found. This function scans from position 0 to the match position each time, resulting in O(n²) complexity when processing code with many matches.

Solution: The optimization replaces these repeated scans with incremental string state tracking directly in the main loop. Instead of rescanning from the beginning for each match, the code maintains in_string, string_char, and last_checked_pos variables that preserve state between iterations. When a new match is found, only the code between last_checked_pos and match_start is scanned to update the string state.

Performance Impact

The line profiler data clearly shows the improvement:

  • Original: is_inside_string() consumed 0.618s (95.2% of transform time) with 432 calls scanning 887,510 characters total
  • Optimized: The inline tracking logic in transform() consumes only 0.021s (33% of transform time) by scanning just 28,273 characters incrementally

Test results demonstrate strong gains on workloads with many matches:

  • test_transform_many_invocations: 12.3ms → 4.84ms (155% faster)
  • test_transform_large_code_file: 40.6ms → 14.0ms (191% faster)
  • test_transform_alternating_patterns: 2.64ms → 519μs (408% faster)
  • test_transform_mixed_qualified_names: 14.0ms → 5.14ms (173% faster)

The optimization particularly benefits code with frequent expect() calls, as each avoided is_inside_string() call saves scanning hundreds or thousands of characters. This makes the transformer significantly faster on realistic test files with multiple assertions.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 98 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Click to see Generated Regression Tests
import re

import pytest  # used for our unit tests
from codeflash.discovery.functions_to_optimize import FunctionToOptimize
# Import the module under test and helper symbols.
from codeflash.languages.javascript.instrument import (ExpectCallTransformer,
                                                       is_inside_string,
                                                       split_call_args)

# Helper to build a FunctionToOptimize instance without relying on unknown constructor.
# We use __new__ to create a real instance of the real class and then set the
# attributes that ExpectCallTransformer will read (function_name and qualified_name).
def _make_fto(function_name: str, qualified_name: str) -> FunctionToOptimize:
    fto = FunctionToOptimize.__new__(FunctionToOptimize)  # real instance, no constructor call
    # set the attributes used by ExpectCallTransformer
    setattr(fto, "function_name", function_name)
    setattr(fto, "qualified_name", qualified_name)
    return fto

def test_is_inside_string_simple_quotes():
    # Verify simple single/double/backtick string detection at various positions.
    code = 'const s = "hello \\"world\\""; const t = \'a,b,c\'; const u = `template ${expr}`;'
    # Position inside the double-quoted "hello \"world\"" (inside word world)
    pos_inside_double = code.index("world") + 2

    # Position inside the single-quoted 'a,b,c'
    pos_inside_single = code.index("a,b,c") + 1

    # Position inside the backtick template (inside template string)
    pos_inside_backtick = code.index("template") + 2

    # Position outside any string (between tokens)
    pos_outside = code.index("const t")

def test_split_call_args_various_cases():

    # Simple thisArg with remaining args
    s = "thisArg, a, b, c"
    this_arg, rest = split_call_args(s)

    # Nested structures containing commas and brackets should not split inside them
    s2 = "thisArg, [1, 2, {x: 'a,b'}], someFunc(1,2)"
    this_arg2, rest2 = split_call_args(s2)

    # String arguments with escaped quotes and commas
    s3 = r"self, 'a\,b', \"c,d\", `e,f`"
    this_arg3, rest3 = split_call_args(s3)

def test_split_call_args_handles_template_literals_and_escapes():
    # Complex call args with template literals and escaped characters.
    s = r"""thisArg, `a,${x},b`, "escaped\"\,comma", func({a:1, b:[1,2,3]})"""
    this_arg, rest = split_call_args(s)
import pytest
from codeflash.discovery.functions_to_optimize import FunctionToOptimize
from codeflash.languages.javascript.instrument import (ExpectCallTransformer,
                                                       is_inside_string,
                                                       split_call_args)

# Helper function to create FunctionToOptimize instances
def create_function_to_optimize(
    function_name: str = "myFunc",
    qualified_name: str = "myFunc",
    file_path: str = "test.js",
) -> FunctionToOptimize:
    """Create a real FunctionToOptimize instance for testing."""
    return FunctionToOptimize(
        function_name=function_name,
        qualified_name=qualified_name,
        file_path=file_path,
        start_line=1,
        end_line=10,
    )

def test_transform_basic_expect_call():
    """Test transformation of a basic expect().toBe() call."""
    func_to_optimize = create_function_to_optimize("myFunc", "myFunc")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(myFunc(5)).toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 16.1μs -> 16.0μs (0.877% faster)

def test_transform_with_multiple_invocations():
    """Test that multiple expect calls are all transformed."""
    func_to_optimize = create_function_to_optimize("add", "add")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(add(1, 2)).toBe(3); expect(add(5, 5)).toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 27.6μs -> 27.1μs (1.66% faster)

def test_transform_with_not_chain():
    """Test transformation with .not. in assertion chain."""
    func_to_optimize = create_function_to_optimize("isNull", "isNull")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(isNull(x)).not.toBe(true);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 16.1μs -> 16.1μs (0.373% faster)

def test_transform_with_resolves_chain():
    """Test transformation with .resolves. in assertion chain."""
    func_to_optimize = create_function_to_optimize("asyncFunc", "asyncFunc")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(asyncFunc()).resolves.toBe(42);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 16.2μs -> 16.1μs (0.871% faster)

def test_transform_with_dot_call_syntax():
    """Test transformation of .call() syntax."""
    func_to_optimize = create_function_to_optimize("calculate", "calculate")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(calculate.call(this, 5)).toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 18.9μs -> 18.9μs (0.000% faster)

def test_transform_preserves_unrelated_code():
    """Test that code without expect calls is preserved."""
    func_to_optimize = create_function_to_optimize("myFunc", "myFunc")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "const x = 5; const y = 10;"
    codeflash_output = transformer.transform(code); result = codeflash_output # 3.52μs -> 3.58μs (1.65% slower)

def test_transform_with_assertion_args():
    """Test transformation with assertion that has arguments."""
    func_to_optimize = create_function_to_optimize("round", "round")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(round(3.14)).toBeCloseTo(3.1, 1);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 16.3μs -> 15.8μs (2.86% faster)

def test_transform_with_no_arg_assertion():
    """Test transformation with no-arg assertion like toBeTruthy."""
    func_to_optimize = create_function_to_optimize("isValid", "isValid")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(isValid()).toBeTruthy();"
    codeflash_output = transformer.transform(code); result = codeflash_output # 14.0μs -> 13.5μs (3.94% faster)

def test_transform_skips_expect_in_string():
    """Test that expect calls inside string literals are skipped."""
    func_to_optimize = create_function_to_optimize("myFunc", "myFunc")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = '// Test "expect(myFunc(5)).toBe(10);"'
    codeflash_output = transformer.transform(code); result = codeflash_output # 7.84μs -> 7.85μs (0.115% slower)

def test_transform_with_object_method():
    """Test transformation with object method call."""
    func_to_optimize = create_function_to_optimize("calculate", "obj.calculate")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(obj.calculate(10)).toBe(20);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 7.37μs -> 7.36μs (0.149% faster)

def test_is_inside_string_single_quote():
    """Test is_inside_string with single quotes."""
    code = "const x = 'hello';"

def test_is_inside_string_double_quote():
    """Test is_inside_string with double quotes."""
    code = 'const x = "hello";'

def test_is_inside_string_with_escaped_quote():
    """Test is_inside_string with escaped quotes."""
    code = 'const x = "he\\"llo";'

def test_split_call_args_single_arg():
    """Test split_call_args with single argument."""
    this_arg, remaining = split_call_args("this")

def test_split_call_args_multiple_args():
    """Test split_call_args with multiple arguments."""
    this_arg, remaining = split_call_args("this, a, b")

def test_split_call_args_with_nested_parens():
    """Test split_call_args with nested parentheses."""
    this_arg, remaining = split_call_args("this, func(x, y), z")

def test_split_call_args_empty_string():
    """Test split_call_args with empty string."""
    this_arg, remaining = split_call_args("")

def test_transform_with_whitespace_variations():
    """Test transformation with various whitespace patterns."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(  fn(  5  )  ).toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 16.6μs -> 16.7μs (0.598% slower)

def test_transform_with_multiline_code():
    """Test transformation with code spanning multiple lines."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(fn(5))\n  .toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 15.0μs -> 14.9μs (0.268% faster)

def test_transform_nested_function_calls():
    """Test transformation with nested function calls in arguments."""
    func_to_optimize = create_function_to_optimize("outer", "outer")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(outer(inner(5))).toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 15.5μs -> 15.2μs (1.92% faster)

def test_transform_with_string_arg():
    """Test transformation with string argument containing special chars."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = 'expect(fn("hello.world")).toBe("result");'
    codeflash_output = transformer.transform(code); result = codeflash_output # 16.5μs -> 16.6μs (0.302% slower)

def test_transform_with_object_in_args():
    """Test transformation with object literal in arguments."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(fn({a: 1, b: 2})).toBe(true);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 15.6μs -> 15.5μs (0.710% faster)

def test_transform_with_array_in_args():
    """Test transformation with array literal in arguments."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(fn([1, 2, 3])).toBe(6);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 14.6μs -> 14.7μs (0.816% slower)

def test_transform_with_template_literal():
    """Test transformation with template literal in arguments."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(fn(`hello ${x}`)).toBe(true);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 15.9μs -> 15.8μs (1.08% faster)

def test_transform_qualified_name_mismatch():
    """Test that qualified_name with dots requires matching object prefix."""
    func_to_optimize = create_function_to_optimize("calculate", "Math.calculate")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    # This should NOT match because we're calling bare calculate(), not Math.calculate()
    code = "expect(calculate(5)).toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 14.0μs -> 14.1μs (0.504% slower)

def test_transform_no_trailing_semicolon():
    """Test transformation without trailing semicolon."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(fn(5)).toBe(10)"
    codeflash_output = transformer.transform(code); result = codeflash_output # 13.6μs -> 13.4μs (1.43% faster)

def test_transform_with_chained_assertions():
    """Test transformation with multiple assertion methods chained."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(fn()).not.resolves.toBe(null);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 16.9μs -> 17.0μs (0.477% slower)

def test_transform_with_rejects_chain():
    """Test transformation with .rejects. assertion chain."""
    func_to_optimize = create_function_to_optimize("asyncFn", "asyncFn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(asyncFn()).rejects.toThrow();"
    codeflash_output = transformer.transform(code); result = codeflash_output # 15.8μs -> 15.6μs (1.22% faster)

def test_transform_with_method_call_syntax():
    """Test transformation with object.method() calls."""
    func_to_optimize = create_function_to_optimize("process", "calc.process")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(calc.process(5)).toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 7.43μs -> 7.32μs (1.52% faster)

def test_transform_dot_call_with_this_keyword():
    """Test .call() with 'this' as thisArg."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(fn.call(this, 5)).toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 19.2μs -> 18.9μs (1.70% faster)

def test_transform_dot_call_with_object_context():
    """Test .call() with object as thisArg."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(fn.call(obj, 5, 6)).toBe(11);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 18.3μs -> 18.4μs (0.705% slower)

def test_transform_empty_code():
    """Test transformation of empty code."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = ""
    codeflash_output = transformer.transform(code); result = codeflash_output # 901ns -> 932ns (3.33% slower)

def test_transform_code_without_expect():
    """Test transformation of code without any expect calls."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "const x = fn(5); console.log(x);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 4.10μs -> 4.15μs (1.23% slower)

def test_split_call_args_with_whitespace():
    """Test split_call_args with various whitespace."""
    this_arg, remaining = split_call_args("  this  ,  a  ,  b  ")

def test_split_call_args_with_nested_brackets():
    """Test split_call_args with nested brackets."""
    this_arg, remaining = split_call_args("this, [1, [2, 3]], x")

def test_split_call_args_with_nested_braces():
    """Test split_call_args with nested braces."""
    this_arg, remaining = split_call_args("ctx, {a: {b: 1}}, z")

def test_is_inside_string_backtick():
    """Test is_inside_string with template literals (backticks)."""
    code = "const x = `hello`;"

def test_is_inside_string_mixed_quotes():
    """Test is_inside_string doesn't confuse different quote types."""
    code = '''const x = "he'llo";'''

def test_is_inside_string_at_boundary():
    """Test is_inside_string at string boundaries."""
    code = "const x = 'hello';"

def test_transform_with_no_args():
    """Test transformation with function called with no arguments."""
    func_to_optimize = create_function_to_optimize("getValue", "getValue")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(getValue()).toBe(42);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 15.0μs -> 15.2μs (0.989% slower)

def test_transform_with_complex_assertion_args():
    """Test transformation with complex assertion arguments."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "expect(fn(5)).toEqual({a: 1, b: [2, 3]});"
    codeflash_output = transformer.transform(code); result = codeflash_output # 16.2μs -> 16.4μs (1.46% slower)

def test_transform_repeated_function_name_different_context():
    """Test transformation doesn't match function name in different contexts."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code = "myFunction(); expect(fn(5)).toBe(10); anotherFn();"
    codeflash_output = transformer.transform(code); result = codeflash_output # 18.0μs -> 17.6μs (2.05% faster)

def test_transform_with_remove_assertions_false():
    """Test transformation with remove_assertions=False (default)."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(
        func_to_optimize, "captureFunc", remove_assertions=False
    )
    
    code = "expect(fn(5)).toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 13.6μs -> 14.0μs (2.51% slower)

def test_transform_with_remove_assertions_true():
    """Test transformation with remove_assertions=True."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(
        func_to_optimize, "captureFunc", remove_assertions=True
    )
    
    code = "expect(fn(5)).toBe(10);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 13.6μs -> 13.7μs (0.666% slower)

def test_transform_many_invocations():
    """Test transformation with many expect calls."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    # Create code with 100 expect calls
    code_lines = [f"expect(fn({i})).toBe({i * 2});" for i in range(100)]
    code = "\n".join(code_lines)
    
    codeflash_output = transformer.transform(code); result = codeflash_output # 12.3ms -> 4.84ms (155% faster)

def test_transform_large_function_args():
    """Test transformation with large function arguments."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    # Create a function call with many arguments
    large_args = ", ".join(str(i) for i in range(100))
    code = f"expect(fn({large_args})).toBe(result);"
    
    codeflash_output = transformer.transform(code); result = codeflash_output # 66.9μs -> 67.0μs (0.061% slower)

def test_transform_deeply_nested_calls():
    """Test transformation with deeply nested function calls."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    # Create deeply nested calls
    nested_call = "fn(a"
    for i in range(50):
        nested_call += f"(fn({i})"
    nested_call += ")" * 51
    
    code = f"expect({nested_call}).toBe(result);"
    codeflash_output = transformer.transform(code); result = codeflash_output # 68.6μs -> 68.0μs (0.899% faster)

def test_transform_large_code_file():
    """Test transformation on a large code file with mixed content."""
    func_to_optimize = create_function_to_optimize("calculate", "calculate")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    # Create a large code file
    code_parts = []
    for i in range(500):
        if i % 10 == 0:
            code_parts.append(f"expect(calculate({i})).toBe({i * 2});")
        else:
            code_parts.append(f"const x{i} = {i}; console.log(x{i});")
    
    code = "\n".join(code_parts)
    codeflash_output = transformer.transform(code); result = codeflash_output # 40.6ms -> 14.0ms (191% faster)

def test_transform_with_many_chained_assertions():
    """Test transformation with many assertion chain variations."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    # Create various assertion chains
    chains = [
        "expect(fn()).toBe(1);",
        "expect(fn()).not.toBe(2);",
        "expect(fn()).resolves.toBe(3);",
        "expect(fn()).rejects.toThrow();",
        "expect(fn()).not.resolves.toBe(4);",
    ]
    
    code = "\n".join(chains * 20)  # Repeat 20 times
    codeflash_output = transformer.transform(code); result = codeflash_output # 14.2ms -> 5.40ms (164% faster)

def test_transform_code_with_long_lines():
    """Test transformation with very long lines."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    # Create a very long line with expect call
    long_code = "const result = " + " + ".join([f"fn({i})" for i in range(100)])
    long_code += "; expect(fn(999)).toBe(1000);"
    
    codeflash_output = transformer.transform(long_code); result = codeflash_output # 118μs -> 117μs (1.61% faster)

def test_split_call_args_many_nested_levels():
    """Test split_call_args with many levels of nesting."""
    args = "this"
    for i in range(50):
        args += f", func{i}(arg)"
    
    this_arg, remaining = split_call_args(args)

def test_is_inside_string_long_code():
    """Test is_inside_string performance with long code."""
    # Create long code with string near the end
    code = "const x = 5; " * 100
    code += 'const msg = "hello";'
    
    # Position inside the string
    pos = len(code) - 7
    
    # Position outside string
    pos = 10

def test_transform_mixed_qualified_names():
    """Test transformation with multiple different function patterns."""
    func_to_optimize = create_function_to_optimize("fn", "module.fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code_lines = []
    # Add matching calls (should transform)
    for i in range(50):
        code_lines.append(f"expect(module.fn({i})).toBe({i * 2});")
    
    # Add non-matching calls (should not transform)
    for i in range(50):
        code_lines.append(f"expect(fn({i})).toBe({i * 2});")
    
    code = "\n".join(code_lines)
    codeflash_output = transformer.transform(code); result = codeflash_output # 14.0ms -> 5.14ms (173% faster)

def test_transform_alternating_patterns():
    """Test transformation alternating between different syntax patterns."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    code_lines = []
    for i in range(50):
        if i % 2 == 0:
            code_lines.append(f"expect(fn({i})).toBe({i});")
        else:
            code_lines.append(f"expect(fn.call(this, {i})).toBe({i});")
    
    code = "\n".join(code_lines)
    codeflash_output = transformer.transform(code); result = codeflash_output # 2.64ms -> 519μs (408% faster)

def test_transform_performance_no_matches():
    """Test that non-matching code doesn't degrade performance."""
    func_to_optimize = create_function_to_optimize("fn", "fn")
    transformer = ExpectCallTransformer(func_to_optimize, "captureFunc")
    
    # Large code with no expect calls for the target function
    code_lines = [f"otherFunc({i});" for i in range(1000)]
    code = "\n".join(code_lines)
    
    codeflash_output = transformer.transform(code); result = codeflash_output # 732μs -> 712μs (2.80% faster)
# 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-pr1523-2026-02-18T13.29.34 and push.

Codeflash Static Badge

The optimized code achieves a **172% speedup** (85.2ms → 31.3ms) by eliminating a critical O(n²) performance bottleneck in the `transform()` method.

## Key Optimization

**Problem**: The original code called `is_inside_string(code, match.start())` for every regex match found. This function scans from position 0 to the match position each time, resulting in O(n²) complexity when processing code with many matches.

**Solution**: The optimization replaces these repeated scans with **incremental string state tracking** directly in the main loop. Instead of rescanning from the beginning for each match, the code maintains `in_string`, `string_char`, and `last_checked_pos` variables that preserve state between iterations. When a new match is found, only the code between `last_checked_pos` and `match_start` is scanned to update the string state.

## Performance Impact

The line profiler data clearly shows the improvement:
- **Original**: `is_inside_string()` consumed 0.618s (95.2% of transform time) with 432 calls scanning 887,510 characters total
- **Optimized**: The inline tracking logic in transform() consumes only 0.021s (33% of transform time) by scanning just 28,273 characters incrementally

Test results demonstrate strong gains on workloads with many matches:
- `test_transform_many_invocations`: 12.3ms → 4.84ms (155% faster)
- `test_transform_large_code_file`: 40.6ms → 14.0ms (191% faster)
- `test_transform_alternating_patterns`: 2.64ms → 519μs (408% faster)
- `test_transform_mixed_qualified_names`: 14.0ms → 5.14ms (173% faster)

The optimization particularly benefits code with frequent expect() calls, as each avoided `is_inside_string()` call saves scanning hundreds or thousands of characters. This makes the transformer significantly faster on realistic test files with multiple assertions.
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Feb 18, 2026
@claude
Copy link
Contributor

claude bot commented Feb 18, 2026

PR Review Summary

Prek Checks

✅ All checks passed — ruff check and ruff format both passed with no issues.

Mypy

✅ No new type errors introduced by this PR. The only mypy errors are pre-existing issues (missing return type annotations in test methods, missing library stubs for codeflash.code_utils.code_position).

Code Review

✅ No critical issues found.

This PR optimizes ExpectCallTransformer.transform by replacing O(n²) is_inside_string() calls with incremental string state tracking. The optimization is correct:

  • Before: Each regex match called is_inside_string(code, match.start()), which scans from position 0 every time → O(n²) when many matches exist.
  • After: Maintains in_string, string_char, and last_checked_pos state variables, scanning only the delta between consecutive matches → O(n) total.

The incremental tracking logic correctly mirrors the original is_inside_string() function (escape handling, quote type tracking). The last_checked_pos bookkeeping is correct across all code paths (match skipped due to string, successful parse, and parse failure).

Test Coverage

File Stmts (main) Stmts (PR) Coverage (main) Coverage (PR) Change
codeflash/languages/javascript/instrument.py 637 765 67% 73% +6% ✅
  • 69 tests pass on the PR branch (vs 44 on main — 25 new tests from the base branch feat/js-dot-call-instrumentation)
  • Coverage improved by 6 percentage points despite the file growing by 128 statements
  • The optimization commit itself adds ~25 lines of incremental tracking logic, which is exercised by existing string-skipping tests

Last updated: 2026-02-18

@mohammedahmed18 mohammedahmed18 merged commit 4c441c9 into feat/js-dot-call-instrumentation Feb 18, 2026
26 of 28 checks passed
@mohammedahmed18 mohammedahmed18 deleted the codeflash/optimize-pr1523-2026-02-18T13.29.34 branch February 18, 2026 13:38
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.

1 participant