codeflash/tests/test_tracer.py

444 lines
16 KiB
Python
Raw Permalink Normal View History

2025-06-10 02:28:34 +00:00
import contextlib
2025-07-14 00:23:01 +00:00
import dataclasses
import pickle
2025-06-10 02:28:34 +00:00
import sqlite3
import sys
import threading
import time
from collections.abc import Generator
from pathlib import Path
from typing import Any
from unittest.mock import patch
import pytest
2026-01-29 09:39:48 +00:00
2025-07-14 00:23:01 +00:00
from codeflash.code_utils.config_parser import parse_config_file
2025-07-11 05:16:15 +00:00
from codeflash.tracing.tracing_new_process import FakeCode, FakeFrame, Tracer
2025-06-10 02:28:34 +00:00
class TestFakeCode:
def test_fake_code_initialization(self) -> None:
fake_code = FakeCode("test.py", 10, "test_function")
assert fake_code.co_filename == "test.py"
assert fake_code.co_line == 10
assert fake_code.co_name == "test_function"
assert fake_code.co_firstlineno == 0
def test_fake_code_repr(self) -> None:
fake_code = FakeCode("test.py", 10, "test_function")
expected_repr = repr(("test.py", 10, "test_function", None))
assert repr(fake_code) == expected_repr
class TestFakeFrame:
def test_fake_frame_initialization(self) -> None:
fake_code = FakeCode("test.py", 10, "test_function")
fake_frame = FakeFrame(fake_code, None)
assert fake_frame.f_code == fake_code
assert fake_frame.f_back is None
assert fake_frame.f_locals == {}
def test_fake_frame_with_prior(self) -> None:
fake_code1 = FakeCode("test1.py", 5, "func1")
fake_code2 = FakeCode("test2.py", 10, "func2")
fake_frame1 = FakeFrame(fake_code1, None)
fake_frame2 = FakeFrame(fake_code2, fake_frame1)
assert fake_frame2.f_code == fake_code2
assert fake_frame2.f_back == fake_frame1
2025-07-14 00:23:01 +00:00
@dataclasses.dataclass
class TraceConfig:
trace_file: Path
trace_config: dict[str, Any]
result_pickle_file_path: Path
project_root: Path
command: str
2025-06-10 02:28:34 +00:00
class TestTracer:
@pytest.fixture
2025-09-28 05:07:24 +00:00
def trace_config(self, tmp_path: Path) -> Generator[TraceConfig, None, None]:
2025-06-10 02:28:34 +00:00
"""Create a temporary pyproject.toml config file."""
# Create a temporary directory structure
2025-09-28 05:07:24 +00:00
tests_dir = tmp_path / "tests"
2025-06-10 02:28:34 +00:00
tests_dir.mkdir(exist_ok=True)
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
# Use the current working directory as module root so test files are included
current_dir = Path.cwd()
2025-09-28 05:07:24 +00:00
config_path = tmp_path / "pyproject.toml"
2026-01-29 09:39:48 +00:00
config_path.write_text(
f"""
2025-06-10 02:28:34 +00:00
[tool.codeflash]
2025-07-30 06:49:22 +00:00
module-root = "{current_dir.as_posix()}"
tests-root = "{tests_dir.as_posix()}"
2025-06-10 02:28:34 +00:00
test-framework = "pytest"
ignore-paths = []
2026-01-29 09:39:48 +00:00
""",
encoding="utf-8",
)
2025-09-28 05:07:24 +00:00
trace_path = tmp_path / "trace_file.trace"
replay_test_pkl_path = tmp_path / "replay_test.pkl"
2025-07-14 00:23:01 +00:00
config, found_config_path = parse_config_file(config_path)
trace_config = TraceConfig(
trace_file=trace_path,
trace_config=config,
result_pickle_file_path=replay_test_pkl_path,
project_root=current_dir,
command="pytest random",
)
2026-01-29 09:39:48 +00:00
return trace_config
2025-06-10 02:28:34 +00:00
@pytest.fixture(autouse=True)
def reset_tracer_state(self) -> Generator[None, None, None]:
"""Reset the tracer used_once state before each test."""
# Reset the class variable if it exists
if hasattr(Tracer, "used_once"):
delattr(Tracer, "used_once")
yield
# Reset after test as well
if hasattr(Tracer, "used_once"):
delattr(Tracer, "used_once")
2025-07-14 00:23:01 +00:00
def test_tracer_disabled_by_environment(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
"""Test that tracer is disabled when CODEFLASH_TRACER_DISABLE is set."""
with patch.dict("os.environ", {"CODEFLASH_TRACER_DISABLE": "1"}):
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
)
2025-06-10 02:28:34 +00:00
assert tracer.disable is True
2025-07-14 00:23:01 +00:00
def test_tracer_disabled_with_existing_profiler(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
"""Test that tracer is disabled when another profiler is running."""
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
def dummy_profiler(_frame: object, _event: str, _arg: object) -> object:
return dummy_profiler
sys.setprofile(dummy_profiler)
try:
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
)
2025-06-10 02:28:34 +00:00
assert tracer.disable is True
finally:
sys.setprofile(None)
2025-07-14 00:23:01 +00:00
def test_tracer_initialization_normal(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
"""Test normal tracer initialization."""
tracer = Tracer(
2025-07-14 00:23:01 +00:00
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-06-10 02:28:34 +00:00
functions=["test_func"],
max_function_count=128,
timeout=10,
)
assert tracer.disable is False
assert tracer.functions == ["test_func"]
assert tracer.max_function_count == 128
assert tracer.timeout == 10
assert hasattr(tracer, "_db_lock")
2025-07-11 05:16:15 +00:00
assert tracer._db_lock is not None
2025-06-10 02:28:34 +00:00
2025-07-14 00:23:01 +00:00
def test_tracer_timeout_validation(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
with pytest.raises(AssertionError):
2025-07-14 00:23:01 +00:00
Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
timeout=0,
)
2025-06-10 02:28:34 +00:00
with pytest.raises(AssertionError):
2025-07-14 00:23:01 +00:00
Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
timeout=-5,
)
def test_tracer_context_manager_disabled(self, trace_config: TraceConfig) -> None:
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
disable=True,
)
2025-06-10 02:28:34 +00:00
with tracer:
pass
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
# When disabled, the tracer doesn't create a trace file
# Note: output_file attribute won't exist when disabled, so we check if disable is True
assert tracer.disable is True
2025-06-10 02:28:34 +00:00
2025-07-14 00:23:01 +00:00
def test_tracer_function_filtering(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
"""Test that tracer respects function filtering."""
if hasattr(Tracer, "used_once"):
delattr(Tracer, "used_once")
def test_function() -> int:
return 42
def other_function() -> int:
return 24
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
functions=["test_function"],
)
2025-06-10 02:28:34 +00:00
with tracer:
test_function()
other_function()
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
if tracer.output_file.exists():
con = sqlite3.connect(tracer.output_file)
2025-06-10 02:28:34 +00:00
cursor = con.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='function_calls'")
if cursor.fetchone():
cursor.execute("SELECT function FROM function_calls WHERE function = 'test_function'")
cursor.fetchall()
cursor.execute("SELECT function FROM function_calls WHERE function = 'other_function'")
cursor.fetchall()
con.close()
2025-07-14 00:23:01 +00:00
def test_tracer_max_function_count(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
def counting_function(n: int) -> int:
return n * 2
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
max_function_count=3,
)
2025-06-10 02:28:34 +00:00
with tracer:
for i in range(5):
counting_function(i)
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
assert tracer.trace_count <= 3, "Tracer should limit the number of traced functions to max_function_count"
2025-07-14 00:23:01 +00:00
def test_tracer_timeout_functionality(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
def slow_function() -> str:
time.sleep(0.1)
return "done"
tracer = Tracer(
2025-07-14 00:23:01 +00:00
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-06-10 02:28:34 +00:00
timeout=1, # 1 second timeout
)
with tracer:
slow_function()
2025-07-14 00:23:01 +00:00
def test_tracer_threading_safety(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
"""Test that tracer works correctly with threading."""
results = []
def thread_function(n: int) -> None:
results.append(n * 2)
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
)
2025-06-10 02:28:34 +00:00
with tracer:
threads = []
for i in range(3):
thread = threading.Thread(target=thread_function, args=(i,))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
assert len(results) == 3
2025-07-14 00:23:01 +00:00
def test_simulate_call(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
"""Test the simulate_call method."""
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
)
2025-06-10 02:28:34 +00:00
tracer.simulate_call("test_simulation")
2025-07-14 00:23:01 +00:00
def test_simulate_cmd_complete(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
"""Test the simulate_cmd_complete method."""
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
)
2025-06-10 02:28:34 +00:00
tracer.simulate_call("test")
tracer.simulate_cmd_complete()
2025-07-14 00:23:01 +00:00
def test_runctx_method(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
"""Test the runctx method for executing code with tracing."""
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
)
2025-06-10 02:28:34 +00:00
global_vars = {"x": 10}
local_vars = {}
result = tracer.runctx("y = x * 2", global_vars, local_vars)
assert result == tracer
assert local_vars["y"] == 20
2025-07-14 00:23:01 +00:00
def test_tracer_handles_class_methods(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
"""Test that tracer correctly handles class methods."""
# Ensure tracer hasn't been used yet in this test
if hasattr(Tracer, "used_once"):
delattr(Tracer, "used_once")
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
class TestClass:
def instance_method(self) -> str:
return "instance"
@classmethod
def class_method(cls) -> str:
return "class"
@staticmethod
def static_method() -> str:
return "static"
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
)
2025-06-10 02:28:34 +00:00
with tracer:
obj = TestClass()
instance_result = obj.instance_method()
class_result = TestClass.class_method()
static_result = TestClass.static_method()
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
if tracer.output_file.exists():
con = sqlite3.connect(tracer.output_file)
2025-06-10 02:28:34 +00:00
cursor = con.cursor()
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='function_calls'")
if cursor.fetchone():
# Query for all function calls
cursor.execute("SELECT function, classname FROM function_calls")
calls = cursor.fetchall()
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
function_names = [call[0] for call in calls]
class_names = [call[1] for call in calls if call[1] is not None]
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
assert "instance_method" in function_names
assert "class_method" in function_names
assert "static_method" in function_names
assert "TestClass" in class_names
else:
pytest.fail("No function_calls table found in trace file")
con.close()
2025-07-14 00:23:01 +00:00
def test_tracer_handles_exceptions_gracefully(self, trace_config: TraceConfig) -> None:
2025-06-10 02:28:34 +00:00
"""Test that tracer handles exceptions in traced code gracefully."""
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
def failing_function() -> None:
raise ValueError("Test exception")
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
)
2025-06-10 02:28:34 +00:00
with tracer, contextlib.suppress(ValueError):
failing_function()
2025-07-14 00:23:01 +00:00
def test_tracer_with_complex_arguments(self, trace_config: TraceConfig) -> None:
2025-07-11 05:16:15 +00:00
def complex_function(
data_dict: dict[str, Any], nested_list: list[list[int]], func_arg: object = lambda x: x
) -> int:
2025-06-10 02:28:34 +00:00
return len(data_dict) + len(nested_list)
2025-07-14 00:23:01 +00:00
tracer = Tracer(
config=trace_config.trace_config,
project_root=trace_config.project_root,
result_pickle_file_path=trace_config.result_pickle_file_path,
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
command=trace_config.command,
2025-07-14 00:23:01 +00:00
)
2025-06-10 02:28:34 +00:00
expected_dict = {"key": "value", "nested": {"inner": "data"}}
expected_list = [[1, 2], [3, 4], [5, 6]]
expected_func = lambda x: x * 2
with tracer:
2025-07-11 05:16:15 +00:00
complex_function(expected_dict, expected_list, func_arg=expected_func)
2025-07-14 00:23:01 +00:00
assert trace_config.result_pickle_file_path.exists()
pickled = pickle.load(trace_config.result_pickle_file_path.open("rb"))
assert pickled["replay_test_file_path"].exists()
2025-06-10 02:28:34 +00:00
tracer improvements (#970) * Consolidate FunctionRanker: merge rank/rerank/filter methods into single rank_functions * calculate in own file time remove unittests remnants * implement suggestions * cleanup code * let's make it clear it's an sqlite3 db * forgot this one * cleanup * tessl add * improve filtering * cleanup * Optimize FunctionRanker.get_function_stats_summary (#971) The optimization replaces an O(N) linear search through all functions with an O(1) hash table lookup followed by iteration over only matching function names. **Key Changes:** - Added `_function_stats_by_name` index in `__init__` that maps function names to lists of (key, stats) tuples - Modified `get_function_stats_summary` to first lookup candidates by function name, then iterate only over those candidates **Why This is Faster:** The original code iterates through ALL function stats (22,603 iterations in the profiler results) for every lookup. The optimized version uses a hash table to instantly find only the functions with matching names, then iterates through just those candidates (typically 1-2 functions). **Performance Impact:** - **Small datasets**: 15-30% speedup as shown in basic test cases - **Large datasets**: Dramatic improvement - the `test_large_scale_performance` case with 900 functions shows **3085% speedup** (66.7μs → 2.09μs) - **Overall benchmark**: 2061% speedup demonstrates the optimization scales excellently with dataset size **When This Optimization Shines:** - Large codebases with many profiled functions (where the linear search becomes expensive) - Repeated function lookups (if this method is called frequently) - Cases with many unique function names but few duplicates per name The optimization maintains identical behavior while transforming the algorithm from O(N) per lookup to O(average functions per name) per lookup, which is typically O(1) in practice. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Revert "let's make it clear it's an sqlite3 db" This reverts commit 713f13558fe6abf23e7cf1e0f7f4bd478d0cbf55. * cleanup trace file * cleanup * addressable time * Optimize TestResults.add The optimization applies **local variable caching** to eliminate repeated attribute lookups on `self.test_result_idx` and `self.test_results`. **Key Changes:** - Added `test_result_idx = self.test_result_idx` and `test_results = self.test_results` to cache references locally - Used these local variables instead of accessing `self.*` attributes multiple times **Why This Works:** In Python, attribute access (e.g., `self.test_result_idx`) involves dictionary lookups in the object's `__dict__`, which is slower than accessing local variables. By caching these references, we eliminate redundant attribute resolution overhead on each access. **Performance Impact:** The line profiler shows the optimization reduces total execution time from 12.771ms to 19.482ms in the profiler run, but the actual runtime improved from 2.13ms to 1.89ms (12% speedup). The test results consistently show 10-20% improvements across various scenarios, particularly benefiting: - Large-scale operations (500+ items): 14-16% faster - Multiple unique additions: 15-20% faster - Mixed workloads with duplicates: 7-15% faster **Real-World Benefits:** This optimization is especially valuable for high-frequency test result collection scenarios where the `add` method is called repeatedly in tight loops, as the cumulative effect of eliminating attribute lookups becomes significant at scale. * bugfix * cleanup * type checks * pre-commit * ⚡️ Speed up function `get_cached_gh_event_data` by 13% (#975) * Optimize get_cached_gh_event_data The optimization replaces `Path(event_path).open(encoding="utf-8")` with the built-in `open(event_path, encoding="utf-8")`, achieving a **12% speedup** by eliminating unnecessary object allocation overhead. **Key optimization:** - **Removed Path object creation**: The original code creates a `pathlib.Path` object just to call `.open()` on it, when the built-in `open()` function can directly accept the string path from `event_path`. - **Reduced memory allocation**: Avoiding the intermediate `Path` object saves both allocation time and memory overhead. **Why this works:** In Python, `pathlib.Path().open()` internally calls the same file opening mechanism as the built-in `open()`, but with additional overhead from object instantiation and method dispatch. Since `event_path` is already a string from `os.getenv()`, passing it directly to `open()` is more efficient. **Performance impact:** The test results show consistent improvements across all file-reading scenarios: - Simple JSON files: 12-20% faster - Large files (1000+ elements): 3-27% faster - Error cases (missing files): Up to 71% faster - The cached calls remain unaffected (0% change as expected) **Workload benefits:** Based on the function references, `get_cached_gh_event_data()` is called by multiple GitHub-related utility functions (`get_pr_number()`, `is_repo_a_fork()`, `is_pr_draft()`). While the `@lru_cache(maxsize=1)` means the file is only read once per program execution, this optimization reduces the initial cold-start latency for GitHub Actions workflows or CI/CD pipelines where these functions are commonly used. The optimization is particularly effective for larger JSON files and error handling scenarios, making it valuable for robust CI/CD environments that may encounter various file conditions. * ignore --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * ⚡️ Speed up function `function_is_a_property` by 60% (#974) * Optimize function_is_a_property The optimized version achieves a **60% speedup** by replacing Python's `any()` generator expression with a manual loop and making three key micro-optimizations: **What was optimized:** 1. **Replaced `isinstance()` with `type() is`**: Direct type comparison (`type(node) is ast_Name`) is faster than `isinstance(node, ast.Name)` for AST nodes where subclassing is rare 2. **Eliminated repeated lookups**: Cached `"property"` as `property_id` and `ast.Name` as `ast_Name` in local variables to avoid global/attribute lookups in the loop 3. **Manual loop with early return**: Replaced `any()` generator with explicit `for` loop that returns `True` immediately upon finding a match, avoiding generator overhead **Why it's faster:** - The `any()` function creates generator machinery that adds overhead, especially for small decorator lists - `isinstance()` performs multiple checks while `type() is` does a single identity comparison - Local variable access is significantly faster than repeated global/attribute lookups in tight loops **Performance characteristics from tests:** - **Small decorator lists** (1-3 decorators): 50-80% faster due to reduced per-iteration overhead - **Large decorator lists** (1000+ decorators): 55-60% consistent speedup, with early termination providing additional benefits when `@property` appears early - **Empty decorator lists**: 77% faster due to avoiding `any()` generator setup entirely **Impact on workloads:** Based on the function references, this function is called during AST traversal in `visit_FunctionDef` and `visit_AsyncFunctionDef` methods - likely part of a code analysis pipeline that processes many functions. The 60% speedup will be particularly beneficial when analyzing codebases with many decorated functions, as this optimization reduces overhead in a hot path that's called once per function definition. * format --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Kevin Turcios <turcioskevinr@gmail.com> * Optimize function_is_a_property (#976) The optimization achieves an **11% speedup** through two key changes: **1. Constant Hoisting:** The original code repeatedly assigns `property_id = "property"` and `ast_name = ast.Name` on every function call. The optimized version moves these to module-level constants `_property_id` and `_ast_name`, eliminating 4,130 redundant assignments per profiling run (saving ~2.12ms total time). **2. isinstance() vs type() comparison:** Replaced `type(node) is ast_name` with `isinstance(node, _ast_name)`. While both are correct for AST nodes (which use single inheritance), `isinstance()` is slightly more efficient for type checking in Python's implementation. **Performance Impact:** The function is called in AST traversal loops when discovering functions to optimize (`visit_FunctionDef` and `visit_AsyncFunctionDef`). Since these visitors process entire codebases, the 11% per-call improvement compounds significantly across large projects. **Test Case Performance:** The optimization shows consistent gains across all test scenarios: - **Simple cases** (no decorators): 29-42% faster due to eliminated constant assignments - **Property detection cases**: 11-26% faster from combined optimizations - **Large-scale tests** (500-1000 functions): 18.5% faster, demonstrating the cumulative benefit when processing many functions The optimizations are particularly effective for codebases with many function definitions, where this function gets called repeatedly during AST analysis. Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * Address PR review comments - Add mkdir for test file directory to prevent FileNotFoundError - Use addressable_time_ns for importance filtering instead of own_time_ns - Remove unnecessary list() wrappers in make_pstats_compatible - Remove old .sqlite3 file with wrong extension Co-Authored-By: Warp <agent@warp.dev> * Check addressable_time_ns instead of own_time_ns for filtering This ensures we consider functions that may have low own_time but high time in first-order dependent functions (callees). Co-Authored-By: Warp <agent@warp.dev> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: Saurabh Misra <misra.saurabh1@gmail.com> Co-authored-by: Warp <agent@warp.dev>
2025-12-19 03:32:49 +00:00
if tracer.output_file.exists():
con = sqlite3.connect(tracer.output_file)
2025-06-10 02:28:34 +00:00
cursor = con.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='function_calls'")
if cursor.fetchone():
cursor.execute("SELECT args FROM function_calls WHERE function = 'complex_function'")
result = cursor.fetchone()
assert result is not None, "Function complex_function should be traced"
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
# Deserialize the arguments
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
traced_args = pickle.loads(result[0])
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
assert "data_dict" in traced_args
assert "nested_list" in traced_args
assert "func_arg" in traced_args
2025-07-11 05:16:15 +00:00
2025-06-10 02:28:34 +00:00
assert traced_args["data_dict"] == expected_dict
assert traced_args["nested_list"] == expected_list
assert callable(traced_args["func_arg"])
assert traced_args["func_arg"](2) == 4
assert len(traced_args["nested_list"]) == 3
else:
pytest.fail("No function_calls table found in trace file")
con.close()