-
Notifications
You must be signed in to change notification settings - Fork 21
fix --benchmark not working on codeflash itself #1028
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
The optimization replaces the general-purpose `_split_top_level_args()` method with a specialized `_first_top_level_arg()` method that extracts only the first argument from a comma-separated argument list. **Key Performance Improvement:** The original implementation (`_split_top_level_args()`) unnecessarily parsed *all* top-level arguments by: 1. Iterating through the entire string character by character 2. Building a list (`current`) and accumulating characters for each argument 3. Joining those characters into strings for every argument 4. Collecting all arguments into a result list 5. Returning the entire list when only `arg_parts[0]` was ever used The optimized version (`_first_top_level_arg()`) short-circuits this process by: 1. Scanning only until the first top-level comma is found 2. Immediately returning a slice of the original string (`args[:i].strip()`) 3. Avoiding list construction and string joining entirely 4. If no comma exists, returning the whole string stripped **Why This Is Faster:** String slicing in Python is O(n) but with very low constant factors (native C implementation). The original approach had higher overhead from: - Multiple list append operations (`current.append(char)`) - String joining operations (`"".join(current)`) performed for *every* argument - List construction for the result array - Multiple strip() calls on all arguments when only the first was needed **Performance Results:** The line profiler shows the critical line dropping from **19.678 ms (79.2% of function time)** to **12.388 ms (62.2% of function time)** - a **~37% speedup** on that specific operation. This translates to an overall **25% speedup** in the full code runtime (2.40ms → 1.92ms). **Test Case Analysis:** The optimization particularly benefits test cases with complex unittest assertions containing multiple arguments: - `test_unittest_with_nested_args_and_commas`: 30.6-38.2% faster - `test_unittest_args_with_kwargs_and_no_top_level_comma`: 32.6% faster - Large-scale tests with many unittest assertions: 29.1-54.5% faster - Complex multi-argument assertions: up to 125% faster Cases with simple asserts or non-matching lines see minimal change, as expected since they don't invoke the modified code path.
…leanup.transform_asserts-mk6lp80w ⚡️ Speed up method `AssertCleanup.transform_asserts` by 25%
| depth = 0 | ||
| for i, ch in enumerate(args): | ||
| if ch in "([{": | ||
| depth += 1 | ||
| elif ch in ")]}": | ||
| depth -= 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚡️Codeflash found 11% (0.11x) speedup for AssertCleanup._first_top_level_arg in codeflash/code_utils/concolic_utils.py
⏱️ Runtime : 1.18 milliseconds → 1.07 milliseconds (best of 109 runs)
📝 Explanation and details
The optimized code achieves a 10% speedup by replacing two separate string membership checks with a single dictionary lookup.
Key Optimization:
In the original code, checking whether a character is an opening or closing bracket requires two in operations on string literals:
if ch in "([{": # Check if opening bracket
depth += 1
elif ch in ")]}": # Check if closing bracket
depth -= 1The optimized version consolidates this into a single dictionary lookup:
_depth_changes = {
'(': 1, '[': 1, '{': 1,
')': -1, ']': -1, '}': -1
}
if ch in _depth_changes:
depth += _depth_changes[ch]Why This Is Faster:
- Single lookup vs. two checks: Dictionary membership testing (
ch in _depth_changes) is O(1) and only needs to be performed once, whereas the original code could potentially perform two string membership checks per character - Direct value retrieval: The dictionary immediately provides both the "is this a bracket?" check and the depth change value in one operation, eliminating the need for separate conditional branches
- Reduced branching: From 3 branches (
if/elif/elif) down to 2 branches (if/elif), which reduces branch prediction overhead
Performance Profile:
From the line profiler results, the optimization particularly improves the two hottest lines:
- Bracket checking: Original spent ~44% of time (25.2% + 19.1%) on the two
ch inchecks; optimized spends ~31% on the single dictionary check - The overall loop iteration time improved from 29% to 34.8% (proportionally faster relative to reduced total time)
Test Case Performance:
The optimization performs best on:
- Large-scale tests with many brackets: Tests like
test_long_first_argument(34.4% faster),test_large_list_as_first_argument(27.2% faster), andtest_large_dict_as_first_argument(25.4% faster) show significant gains because they process many bracket characters - Simple cases are slightly slower: Small tests (typically <3μs) show 5-30% slowdowns due to dictionary creation overhead, but these represent negligible absolute time differences (often <500ns)
The optimization trades a small setup cost (creating a 6-entry dictionary) for faster per-character processing, making it ideal for processing typical argument strings with multiple brackets—the common use case for this parsing utility.
✅ Correctness verification report:
| Test | Status |
|---|---|
| ⚙️ Existing Unit Tests | 🔘 None Found |
| 🌀 Generated Regression Tests | ✅ 125 Passed |
| ⏪ Replay Tests | 🔘 None Found |
| 🔎 Concolic Coverage Tests | ✅ 4 Passed |
| 📊 Tests Coverage | 100.0% |
🌀 Click to see Generated Regression Tests
from codeflash.code_utils.concolic_utils import AssertCleanup
# function to test
# The tests below exercise AssertCleanup._first_top_level_arg extensively.
# Each test is documented with comments describing the scenario and the reasoning.
# Create a shared AssertCleanup instance used across tests to avoid repeated construction.
AC = AssertCleanup()
def test_basic_single_argument_no_comma():
# Basic: single identifier without any commas should return the trimmed input unchanged.
inp = "foo"
codeflash_output = AC._first_top_level_arg(inp) # 1.52μs -> 1.90μs (20.0% slower)
# Basic: leading/trailing whitespace should be stripped from the result.
inp = " bar "
codeflash_output = AC._first_top_level_arg(inp) # 1.19μs -> 1.35μs (11.9% slower)
def test_basic_top_level_comma_splitting():
# Basic: simple top-level comma splits arguments; should return everything before first top-level comma.
codeflash_output = AC._first_top_level_arg("a, b") # 1.80μs -> 2.06μs (12.6% slower)
codeflash_output = AC._first_top_level_arg(" a ,b,c") # 1.10μs -> 1.20μs (8.32% slower)
# Multiple commas: first top-level comma determines the split.
codeflash_output = AC._first_top_level_arg("first, second, third") # 791ns -> 1.04μs (24.1% slower)
def test_nested_parentheses_are_respected():
# Nested parentheses: commas inside parentheses are NOT top-level and should be ignored.
inp = "func(arg1, arg2), other"
# The first argument should include the entire func(...) with internal commas.
codeflash_output = AC._first_top_level_arg(inp) # 2.92μs -> 3.21μs (9.30% slower)
# More deeply nested parentheses should still preserve internal commas.
inp = "outer(inner1, inner2(inner3, inner4)), x"
codeflash_output = AC._first_top_level_arg(inp) # 3.02μs -> 2.87μs (5.24% faster)
def test_mixed_brackets_and_braces():
# Brackets [] and braces {} are tracked the same way as parentheses by depth counting.
codeflash_output = AC._first_top_level_arg("[1,2], 3") # 2.33μs -> 2.47μs (5.66% slower)
codeflash_output = AC._first_top_level_arg("{a: (1,2)}, next") # 1.63μs -> 1.49μs (9.38% faster)
# A mixture of different bracket types nested together.
inp = "({[a, b], c}, d), tail"
# The first top-level comma is after the closing parenthesis of the mixture.
codeflash_output = AC._first_top_level_arg(inp) # 1.72μs -> 1.68μs (2.38% faster)
def test_unbalanced_closing_bracket_behavior():
# Edge: leading unmatched closing bracket decreases depth below zero.
# The implementation does not special-case negative depths, so a comma after an unmatched
# closing bracket at depth -1 will not be recognized as top-level.
inp = "), next"
# Because the comma occurs when depth == -1, it should NOT be treated as top-level,
# and the function returns the whole trimmed string.
codeflash_output = AC._first_top_level_arg(inp) # 1.94μs -> 2.29μs (15.3% slower)
# Edge: extra closing characters somewhere in the string should not make the function
# raise; it should still return the trimmed entire string if no comma at depth 0 found.
inp = "value ) , more"
codeflash_output = AC._first_top_level_arg(inp) # 1.37μs -> 1.52μs (9.85% slower)
def test_commas_inside_quotes_are_treated_as_top_level_by_implementation():
# Important: The implementation only tracks bracket depth and does not treat quotes specially.
# Therefore, commas inside quoted strings are considered top-level and will split.
inp = '"a,b", c'
# The comma inside the quotes is at depth 0 (quotes aren't tracked), so the function
# will return the content up to that comma.
codeflash_output = AC._first_top_level_arg(inp) # 1.82μs -> 2.10μs (13.4% slower)
# Single quotes behave the same way according to current implementation.
inp2 = "'x,y', z"
codeflash_output = AC._first_top_level_arg(inp2) # 681ns -> 902ns (24.5% slower)
def test_empty_and_only_commas_and_spaces():
# Edge: empty string should return empty string (after stripping).
codeflash_output = AC._first_top_level_arg("") # 1.07μs -> 1.39μs (23.0% slower)
codeflash_output = AC._first_top_level_arg(" ") # 1.03μs -> 1.08μs (4.62% slower)
# Edge: a leading comma should yield empty string as the first argument.
codeflash_output = AC._first_top_level_arg(", rest") # 761ns -> 1.00μs (24.1% slower)
# Edge: string consisting only of commas and whitespace; first comma yields empty first arg.
codeflash_output = AC._first_top_level_arg(", , ,") # 410ns -> 561ns (26.9% slower)
def test_tricky_spacing_and_commas_with_nested_structures():
# Ensure trimming and detection work with various spacing patterns.
inp = " func( 1 ,2 ) , next"
codeflash_output = AC._first_top_level_arg(inp) # 3.11μs -> 3.28μs (5.22% slower)
# Comma directly adjacent to bracket does not confuse detection.
inp2 = "list[1,2],second"
codeflash_output = AC._first_top_level_arg(inp2) # 1.58μs -> 1.53μs (3.26% faster)
def test_multiple_top_level_commas_preserve_only_first_segment():
# When there are multiple top-level commas, only the very first one should determine the cut.
inp = "A, B, C, D"
codeflash_output = AC._first_top_level_arg(inp) # 1.63μs -> 1.95μs (16.5% slower)
# Complex where first comma is inside nested and second is top-level; result should respect that.
inp2 = "f(1,2), g(3,4), h"
codeflash_output = AC._first_top_level_arg(inp2) # 1.34μs -> 1.45μs (7.57% slower)
def test_large_deep_nesting_performance_and_correctness():
# Large-scale: create a deeply nested string with a large number of opening parentheses,
# then an internal comma which must NOT be treated as top-level, and finally a top-level comma.
# Keep the total characters under 1000 to follow the constraints.
depth = 400 # depth << 1000 as required
inner = "1,2" # internal comma which must be ignored
nested = "(" * depth + inner + ")" * depth + ", trailing"
# The function should return the entire nested parentheses (the first top-level argument).
expected = "(" * depth + inner + ")" * depth
codeflash_output = AC._first_top_level_arg(nested) # 46.0μs -> 49.2μs (6.42% slower)
# Another large-scale test: alternating bracket types nested to stress-depth counting.
# Construct a moderate-depth alternating sequence: ({[({[ ... ]})]})
parts = []
pairs = [("(", ")"), ("[", "]"), ("{", "}")]
rep = 120 # ensures under 1000 chars with the content we'll add
for i in range(rep):
o, c = pairs[i % len(pairs)]
parts.append(o)
inner2 = "a,b" # comma inside nested structure
for i in range(rep - 1, -1, -1):
o, c = pairs[i % len(pairs)]
parts.append(c)
large_nested = "".join(parts[:rep]) + inner2 + "".join(parts[rep:]) + ",more"
# The function should return the entire large nested part.
codeflash_output = AC._first_top_level_arg(large_nested) # 12.6μs -> 13.5μs (6.61% slower)
# The tests below assert that slight mutations to the algorithm would be detected.
# For example, if the implementation were changed to treat quotes specially, or to
# count only parentheses and not other bracket types, some of the above assertions
# would fail. These tests therefore help ensure that the exact current semantics
# (depth counting for ()[]{} only, ignoring quotes) are preserved.
def test_comma_in_string_not_ignored_by_current_implementation():
# Re-affirmation that commas inside quotes are not treated specially by the implementation.
# This test would fail if the implementation were mutated to treat strings as bracketed regions.
inp = '"one,two",three'
codeflash_output = AC._first_top_level_arg(inp) # 1.88μs -> 2.24μs (16.1% slower)
def test_unusual_characters_and_unicode_do_not_break_behavior():
# Ensure unicode and other characters do not break scanning logic.
inp = "αβγ(δ,ε), ζ"
# The internal comma should be ignored because it's inside parentheses.
codeflash_output = AC._first_top_level_arg(inp) # 3.24μs -> 3.60μs (10.0% slower)
# Emojis and punctuation are fine as long as parentheses/brackets rules apply.
inp2 = "🙂(a,b), rest"
codeflash_output = AC._first_top_level_arg(inp2) # 1.73μs -> 1.88μs (7.97% slower)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.import pytest
from codeflash.code_utils.concolic_utils import AssertCleanup
class TestFirstTopLevelArg:
"""Test suite for AssertCleanup._first_top_level_arg method."""
@pytest.fixture
def cleanup(self):
"""Fixture to provide an AssertCleanup instance for each test."""
return AssertCleanup()
# ========== BASIC TEST CASES ==========
# These tests verify fundamental functionality under normal conditions
def test_single_argument_no_commas(self, cleanup):
"""Test extraction of a single argument with no commas."""
codeflash_output = cleanup._first_top_level_arg("x")
result = codeflash_output # 1.31μs -> 1.73μs (24.2% slower)
def test_single_argument_with_whitespace(self, cleanup):
"""Test extraction of a single argument with leading/trailing whitespace."""
codeflash_output = cleanup._first_top_level_arg(" x ")
result = codeflash_output # 1.74μs -> 2.05μs (15.1% slower)
def test_two_arguments_simple(self, cleanup):
"""Test extraction of first argument from two simple arguments."""
codeflash_output = cleanup._first_top_level_arg("a, b")
result = codeflash_output # 1.77μs -> 1.97μs (10.2% slower)
def test_multiple_arguments_simple(self, cleanup):
"""Test extraction of first argument from multiple simple arguments."""
codeflash_output = cleanup._first_top_level_arg("x, y, z")
result = codeflash_output # 1.69μs -> 1.97μs (14.2% slower)
def test_first_arg_with_parentheses(self, cleanup):
"""Test extraction when first argument contains balanced parentheses."""
codeflash_output = cleanup._first_top_level_arg("func(a), b")
result = codeflash_output # 2.28μs -> 2.63μs (13.3% slower)
def test_first_arg_with_brackets(self, cleanup):
"""Test extraction when first argument contains square brackets."""
codeflash_output = cleanup._first_top_level_arg("[1, 2], x")
result = codeflash_output # 2.34μs -> 2.63μs (11.0% slower)
def test_first_arg_with_braces(self, cleanup):
"""Test extraction when first argument contains curly braces."""
codeflash_output = cleanup._first_top_level_arg("{a: b}, c")
result = codeflash_output # 2.16μs -> 2.43μs (11.1% slower)
def test_nested_parentheses_in_first_arg(self, cleanup):
"""Test extraction when first argument has nested parentheses."""
codeflash_output = cleanup._first_top_level_arg("func(inner(x)), y")
result = codeflash_output # 2.87μs -> 3.06μs (6.22% slower)
def test_whitespace_around_comma(self, cleanup):
"""Test that whitespace around commas is properly handled."""
codeflash_output = cleanup._first_top_level_arg("a , b")
result = codeflash_output # 1.91μs -> 2.27μs (15.9% slower)
def test_no_whitespace_around_comma(self, cleanup):
"""Test extraction with no whitespace around comma."""
codeflash_output = cleanup._first_top_level_arg("a,b,c")
result = codeflash_output # 1.69μs -> 1.95μs (13.4% slower)
# ========== EDGE TEST CASES ==========
# These tests evaluate behavior under extreme or unusual conditions
def test_empty_string(self, cleanup):
"""Test extraction from an empty string."""
codeflash_output = cleanup._first_top_level_arg("")
result = codeflash_output # 1.01μs -> 1.43μs (29.3% slower)
def test_only_whitespace(self, cleanup):
"""Test extraction from a string containing only whitespace."""
codeflash_output = cleanup._first_top_level_arg(" ")
result = codeflash_output # 1.64μs -> 1.85μs (11.4% slower)
def test_only_comma(self, cleanup):
"""Test extraction from a string containing only a comma."""
codeflash_output = cleanup._first_top_level_arg(",")
result = codeflash_output # 1.52μs -> 1.84μs (17.4% slower)
def test_comma_at_start(self, cleanup):
"""Test extraction when string starts with comma."""
codeflash_output = cleanup._first_top_level_arg(", a")
result = codeflash_output # 1.46μs -> 1.81μs (19.4% slower)
def test_multiple_commas_no_args(self, cleanup):
"""Test extraction with multiple consecutive commas."""
codeflash_output = cleanup._first_top_level_arg(",,")
result = codeflash_output # 1.52μs -> 1.75μs (13.1% slower)
def test_comma_inside_parentheses_ignored(self, cleanup):
"""Test that commas inside parentheses are not treated as separators."""
codeflash_output = cleanup._first_top_level_arg("func(a, b), c")
result = codeflash_output # 2.64μs -> 2.86μs (7.42% slower)
def test_comma_inside_brackets_ignored(self, cleanup):
"""Test that commas inside square brackets are not treated as separators."""
codeflash_output = cleanup._first_top_level_arg("[a, b], c")
result = codeflash_output # 2.42μs -> 2.60μs (6.59% slower)
def test_comma_inside_braces_ignored(self, cleanup):
"""Test that commas inside curly braces are not treated as separators."""
codeflash_output = cleanup._first_top_level_arg("{a: b, c: d}, e")
result = codeflash_output # 2.62μs -> 2.88μs (8.70% slower)
def test_deeply_nested_parentheses(self, cleanup):
"""Test extraction with deeply nested parentheses."""
codeflash_output = cleanup._first_top_level_arg("f(g(h(i(j)))), k")
result = codeflash_output # 2.65μs -> 2.90μs (8.36% slower)
def test_mixed_bracket_types_balanced(self, cleanup):
"""Test extraction with mixed bracket types that are balanced."""
codeflash_output = cleanup._first_top_level_arg("func([{a}], b), c")
result = codeflash_output # 3.05μs -> 2.98μs (2.04% faster)
def test_unbalanced_open_parenthesis_in_arg(self, cleanup):
"""Test extraction when first argument has unmatched opening parenthesis at the end."""
# The function should still find the comma after the closing paren
codeflash_output = cleanup._first_top_level_arg("(x, y")
result = codeflash_output # 1.91μs -> 2.12μs (9.93% slower)
def test_string_with_special_characters(self, cleanup):
"""Test extraction with special characters in argument."""
codeflash_output = cleanup._first_top_level_arg("@var, b")
result = codeflash_output # 1.95μs -> 2.27μs (14.1% slower)
def test_numeric_argument(self, cleanup):
"""Test extraction of numeric arguments."""
codeflash_output = cleanup._first_top_level_arg("123, 456")
result = codeflash_output # 1.83μs -> 2.22μs (17.6% slower)
def test_negative_number_argument(self, cleanup):
"""Test extraction of negative numeric arguments."""
codeflash_output = cleanup._first_top_level_arg("-42, x")
result = codeflash_output # 1.79μs -> 2.09μs (14.4% slower)
def test_float_argument(self, cleanup):
"""Test extraction of floating point arguments."""
codeflash_output = cleanup._first_top_level_arg("3.14, x")
result = codeflash_output # 1.87μs -> 2.21μs (15.4% slower)
def test_quoted_string_with_comma(self, cleanup):
"""Test that quoted strings containing commas are not split (commas inside quotes still split due to regex not handling strings)."""
# Note: This function doesn't handle quoted strings specially, so this tests actual behavior
codeflash_output = cleanup._first_top_level_arg('"a,b", c')
result = codeflash_output # 1.80μs -> 2.00μs (10.0% slower)
def test_single_character_argument(self, cleanup):
"""Test extraction of single character arguments."""
codeflash_output = cleanup._first_top_level_arg("x, y, z")
result = codeflash_output # 1.61μs -> 1.93μs (16.6% slower)
def test_argument_with_underscores(self, cleanup):
"""Test extraction of arguments containing underscores."""
codeflash_output = cleanup._first_top_level_arg("my_var, other")
result = codeflash_output # 2.01μs -> 2.33μs (13.4% slower)
def test_argument_with_dots(self, cleanup):
"""Test extraction of arguments containing dots (attribute access)."""
codeflash_output = cleanup._first_top_level_arg("obj.attr, b")
result = codeflash_output # 2.14μs -> 2.42μs (11.2% slower)
def test_multiple_levels_of_brackets(self, cleanup):
"""Test extraction with multiple levels of different bracket types."""
codeflash_output = cleanup._first_top_level_arg("[[{a}]], b")
result = codeflash_output # 2.42μs -> 2.54μs (4.34% slower)
def test_trailing_whitespace_only(self, cleanup):
"""Test extraction when there's trailing whitespace after last argument."""
codeflash_output = cleanup._first_top_level_arg("a, b ")
result = codeflash_output # 1.69μs -> 1.96μs (13.8% slower)
def test_leading_whitespace_only(self, cleanup):
"""Test extraction when there's leading whitespace before first argument."""
codeflash_output = cleanup._first_top_level_arg(" a, b")
result = codeflash_output # 1.99μs -> 2.20μs (9.53% slower)
def test_tab_characters_as_whitespace(self, cleanup):
"""Test extraction with tab characters as whitespace."""
codeflash_output = cleanup._first_top_level_arg("\ta\t,\tb")
result = codeflash_output # 1.89μs -> 2.17μs (12.9% slower)
def test_newline_in_argument(self, cleanup):
"""Test extraction with newline characters."""
codeflash_output = cleanup._first_top_level_arg("a\nb, c")
result = codeflash_output # 1.84μs -> 2.17μs (15.2% slower)
def test_empty_parentheses(self, cleanup):
"""Test extraction with empty parentheses as argument."""
codeflash_output = cleanup._first_top_level_arg("(), b")
result = codeflash_output # 1.85μs -> 2.06μs (10.2% slower)
def test_empty_brackets(self, cleanup):
"""Test extraction with empty square brackets as argument."""
codeflash_output = cleanup._first_top_level_arg("[], b")
result = codeflash_output # 1.88μs -> 2.15μs (12.6% slower)
def test_empty_braces(self, cleanup):
"""Test extraction with empty curly braces as argument."""
codeflash_output = cleanup._first_top_level_arg("{}, b")
result = codeflash_output # 1.87μs -> 2.05μs (8.81% slower)
def test_many_levels_of_parentheses_depth(self, cleanup):
"""Test deep nesting doesn't cause issues with depth tracking."""
# Create a string with 100 levels of nested parentheses
inner = "x"
for _ in range(100):
inner = f"({inner})"
codeflash_output = cleanup._first_top_level_arg(f"{inner}, y")
result = codeflash_output # 11.3μs -> 12.4μs (8.80% slower)
# ========== LARGE SCALE TEST CASES ==========
# These tests assess performance and scalability with large data samples
def test_long_first_argument(self, cleanup):
"""Test extraction of a very long first argument."""
# Create a long argument with 1000 characters
long_arg = "a" * 1000
codeflash_output = cleanup._first_top_level_arg(f"{long_arg}, b")
result = codeflash_output # 61.3μs -> 45.6μs (34.4% faster)
def test_many_arguments(self, cleanup):
"""Test extraction with many comma-separated arguments."""
# Create a string with 500 arguments
args = ", ".join([f"arg{i}" for i in range(500)])
codeflash_output = cleanup._first_top_level_arg(args)
result = codeflash_output # 1.97μs -> 2.34μs (15.8% slower)
def test_deeply_nested_structure(self, cleanup):
"""Test extraction with a deeply nested balanced structure."""
# Create nested structure with 200 levels
inner = "value"
for _ in range(200):
inner = f"f({inner})"
codeflash_output = cleanup._first_top_level_arg(f"{inner}, other")
result = codeflash_output # 34.8μs -> 33.5μs (4.04% faster)
def test_long_string_with_many_brackets(self, cleanup):
"""Test extraction from string with many bracket pairs."""
# Create string with 500 balanced bracket pairs
arg = "".join(["()" for _ in range(500)])
codeflash_output = cleanup._first_top_level_arg(f"{arg}, b")
result = codeflash_output # 54.6μs -> 58.2μs (6.08% slower)
def test_large_list_as_first_argument(self, cleanup):
"""Test extraction when first argument is a large list representation."""
# Create a large list-like structure with 500 elements
list_arg = "[" + ", ".join([str(i) for i in range(500)]) + "]"
codeflash_output = cleanup._first_top_level_arg(f"{list_arg}, b")
result = codeflash_output # 156μs -> 123μs (27.2% faster)
def test_large_dict_as_first_argument(self, cleanup):
"""Test extraction when first argument is a large dict representation."""
# Create a large dict-like structure with 500 key-value pairs
dict_arg = "{" + ", ".join([f"'{i}': {i}" for i in range(500)]) + "}"
codeflash_output = cleanup._first_top_level_arg(f"{dict_arg}, b")
result = codeflash_output # 370μs -> 295μs (25.4% faster)
def test_alternating_bracket_types_large(self, cleanup):
"""Test extraction with alternating bracket types in large structure."""
# Create alternating bracket structure
arg = ""
for i in range(200):
if i % 3 == 0:
arg += "("
elif i % 3 == 1:
arg += "["
else:
arg += "{"
# Close all brackets in reverse order
for i in range(200):
if (199 - i) % 3 == 0:
arg += ")"
elif (199 - i) % 3 == 1:
arg += "]"
else:
arg += "}"
codeflash_output = cleanup._first_top_level_arg(f"{arg}, b")
result = codeflash_output # 21.6μs -> 23.6μs (8.45% slower)
def test_many_whitespace_characters(self, cleanup):
"""Test extraction with excessive whitespace in argument."""
# Create argument with lots of internal spaces
arg = "a" + " " * 500 + "b"
codeflash_output = cleanup._first_top_level_arg(f"{arg}, c")
result = codeflash_output # 30.4μs -> 22.6μs (34.2% faster)
def test_complex_nested_mixed_brackets_large(self, cleanup):
"""Test extraction with complex nesting of all bracket types."""
# Create a complex structure mixing all bracket types
arg = "".join(["".join(["([{}])" for _ in range(50)]) for _ in range(10)])
codeflash_output = cleanup._first_top_level_arg(f"{arg}, other")
result = codeflash_output # 164μs -> 173μs (5.08% slower)
def test_long_argument_whitespace_stripped(self, cleanup):
"""Test that whitespace is properly stripped from very long arguments."""
long_arg = "a" * 500
codeflash_output = cleanup._first_top_level_arg(f" {long_arg} , b")
result = codeflash_output # 30.7μs -> 23.1μs (32.9% faster)
def test_many_nested_function_calls_large(self, cleanup):
"""Test extraction with many nested function calls."""
# Create deeply nested function call structure
arg = "f0(x)"
for i in range(1, 200):
arg = f"f{i}({arg})"
codeflash_output = cleanup._first_top_level_arg(f"{arg}, b")
result = codeflash_output # 66.8μs -> 59.7μs (11.8% faster)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.from codeflash.code_utils.concolic_utils import AssertCleanup
def test_AssertCleanup__first_top_level_arg():
AssertCleanup._first_top_level_arg(AssertCleanup(), "),(,")
def test_AssertCleanup__first_top_level_arg_2():
AssertCleanup._first_top_level_arg(AssertCleanup(), "")🔎 Click to see Concolic Coverage Tests
| Test File::Test Function | Original ⏱️ | Optimized ⏱️ | Speedup |
|---|---|---|---|
codeflash_concolic_4nicknyx/tmpaqmxogui/test_concolic_coverage.py::test_AssertCleanup__first_top_level_arg |
2.02μs | 2.30μs | -12.2% |
codeflash_concolic_4nicknyx/tmpaqmxogui/test_concolic_coverage.py::test_AssertCleanup__first_top_level_arg_2 |
982ns | 1.33μs | -26.3% |
To test or edit this optimization locally git merge codeflash/optimize-pr1028-2026-01-09T18.28.28
| depth = 0 | |
| for i, ch in enumerate(args): | |
| if ch in "([{": | |
| depth += 1 | |
| elif ch in ")]}": | |
| depth -= 1 | |
| # Pre-compute bracket depth changes for O(1) lookup | |
| _depth_changes = {"(": 1, "[": 1, "{": 1, ")": -1, "]": -1, "}": -1} | |
| depth = 0 | |
| for i, ch in enumerate(args): | |
| if ch in _depth_changes: | |
| depth += _depth_changes[ch] |
| # them to import codeflash_trace back, creating a circular import) | ||
| parts = file_path.parts | ||
| # Find the last "codeflash" in path (handles nested paths like .../codeflash/codeflash/...) | ||
| codeflash_indices = [i for i, p in enumerate(parts) if p == "codeflash"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wonder if the .partition optimization you found for pypa packaging could apply here @KRRT7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea, I'll try it out
aseembits93
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_first_top_level_arg should have some unit tests
| arg_parts = self._split_top_level_args(args) | ||
| if arg_parts and arg_parts[0]: | ||
| return f"{indent}{arg_parts[0]}" | ||
| arg_parts = self._first_top_level_arg(args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the older _split_top_level_args is not used anywhere else I believe, you can remove it
| self.assert_re = re.compile(r"\s*assert\s+(.*?)(?:\s*==\s*.*)?$") | ||
| self.unittest_re = re.compile(r"(\s*)self\.assert([A-Za-z]+)\((.*)\)$") | ||
|
|
||
| def _first_top_level_arg(self, args: str) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there could be some edge cases in this function, you should write some unit test cases for this.
Replace list comprehension with string partition operations for cleaner code.
…eflash into fix---benchmark
|
@aseembits93 added tests |
No description provided.