Skip to content

Commit 1502b4d

Browse files
Optimize StandaloneCallTransformer._parse_bracket_standalone_call
The optimized code achieves a **147% speedup** (2.47x faster) by fundamentally changing how the `_find_balanced_parens` method searches through JavaScript code to find matching parentheses. **Key Optimization: Regex-Based Scanning** The original code iterates through **every single character** in the string (20,283 iterations) to find quotes and parentheses. The optimized version uses a precompiled regex pattern (`self._special_re = re.compile(r'["\'`()]')`) to **jump directly between special characters**, reducing iterations from 20,283 to just 1,268 - a **94% reduction in loop iterations**. **Why This Is Faster** 1. **Compiled regex scanning**: The regex engine (implemented in C) can skip over irrelevant characters much faster than Python's character-by-character iteration 2. **Fewer comparisons**: Instead of checking `if char in quotes` on every character, the regex only returns when it finds a relevant character 3. **Reduced overhead**: The optimized loop executes 16x fewer times, eliminating 19,000+ Python bytecode interpretation cycles **Line Profiler Evidence** The `_find_balanced_parens` function shows dramatic improvement: - **Original**: 18.4ms total (20,321 loop iterations @ 182.7ns per hit on the while condition) - **Optimized**: 3.2ms total (1,305 loop iterations @ 194.2ns per hit) - **5.7x faster** for this function alone The while loop body itself drops from consuming 98.3% of function time (checking every character) to the regex search consuming just 22.7% (jumping between special characters). **Trade-offs** The regex approach adds small overhead for each `match.group()` and `match.start()` call (9.3% + 7.5% of optimized time), but this is vastly outweighed by eliminating 19,000 character checks. **Impact** Since `_parse_bracket_standalone_call` spends 98.6% of its time in `_find_balanced_parens`, this optimization cascades up the call stack. This makes the code particularly beneficial when parsing JavaScript files with deeply nested function calls or large argument lists where the parenthesis-matching logic is heavily exercised.
1 parent a3ca8ee commit 1502b4d

1 file changed

Lines changed: 14 additions & 7 deletions

File tree

codeflash/languages/javascript/instrument.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ def __init__(self, function_to_optimize: FunctionToOptimize, capture_func: str)
179179
# Captures: (whitespace)(await )?(object.)*func_name.call(
180180
self._dot_call_pattern = re.compile(rf"(\s*)(await\s+)?((?:\w+\.)*){re.escape(self.func_name)}\.call\s*\(")
181181

182+
# Precompile regex to find next special character (quotes or parentheses)
183+
self._special_re = re.compile(r'["\'`()]')
184+
182185
def transform(self, code: str) -> str:
183186
"""Transform all standalone calls in the code."""
184187
result: list[str] = []
@@ -380,13 +383,18 @@ def _find_balanced_parens(self, code: str, open_paren_pos: int) -> tuple[str | N
380383
s_len = len(s)
381384
quotes = "\"'`"
382385

386+
special_re = self._special_re
387+
383388
while pos < s_len and depth > 0:
384-
char = s[pos]
389+
match = special_re.search(s, pos)
390+
if not match:
391+
return None, -1
392+
393+
char = match.group()
394+
char_pos = match.start()
385395

386-
# Handle string literals
387-
# Note: preserve original escaping semantics (only checks immediate preceding char)
388396
if char in quotes:
389-
prev_char = s[pos - 1] if pos > 0 else None
397+
prev_char = s[char_pos - 1] if char_pos > 0 else None
390398
if prev_char != "\\":
391399
if not in_string:
392400
in_string = True
@@ -399,13 +407,12 @@ def _find_balanced_parens(self, code: str, open_paren_pos: int) -> tuple[str | N
399407
depth += 1
400408
elif char == ")":
401409
depth -= 1
402-
403-
pos += 1
410+
411+
pos = char_pos + 1
404412

405413
if depth != 0:
406414
return None, -1
407415

408-
# slice once
409416
return s[open_paren_pos + 1 : pos - 1], pos
410417

411418
def _parse_bracket_standalone_call(self, code: str, match: re.Match[str]) -> StandaloneCallMatch | None:

0 commit comments

Comments
 (0)