From 9bc7528a9c9719560d2f1aab16d594361fa99c64 Mon Sep 17 00:00:00 2001 From: "codeflash-ai[bot]" <148906541+codeflash-ai[bot]@users.noreply.github.com> Date: Sun, 1 Feb 2026 21:28:58 +0000 Subject: [PATCH] Optimize _prompt_custom_directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The optimized code achieves a **364% speedup** (101ms → 21.7ms) through two targeted optimizations: ## 1. Theme Instance Caching (Primary Optimization) The original code recreated a `CodeflashTheme()` instance on every call to `_get_theme()`. Line profiler shows this function was called 360 times, spending **88.2% of execution time** (133.4ms) just instantiating theme objects. The optimization introduces a module-level cache (`_cached_theme`) that stores the theme after first creation. This reduces `_get_theme()` total time from **151.2ms to 17.4ms** (88.5% reduction), as subsequent calls simply return the cached instance instead of re-instantiating. **Test Impact**: Basic path validation tests show **900-1000% speedup** (265μs → 25μs), stress tests with 50-100 invalid retries show **281-300% speedup** (16ms → 4.2ms), and deeply nested paths improve by **300-500%**. The caching is most effective in scenarios with multiple validation attempts, which is common when users enter incorrect paths. ## 2. Faster Absolute Path Check The original code used `Path(path).is_absolute()` which instantiates a `Path` object just to check if a path is absolute. Line profiler shows this consumed **55.4%** of `validate_relative_directory_path()` time (4.28ms). The optimization replaces this with `os.path.isabs(path)`, a lightweight string-based check that avoids object instantiation. This reduces the absolute path check from **4.28ms to 0.68ms** (84% reduction). ## Why This Works - **Lazy initialization + caching** is a classic pattern for expensive object creation that's needed repeatedly - `os.path.isabs()` is functionally equivalent to `Path().is_absolute()` for validation purposes but avoids the overhead of pathlib's object model - The `CodeflashTheme` initialization likely involves terminal capability detection and color setup, making it expensive to repeat ## Context Considerations While function references aren't available, the fact that `_get_theme()` was called 360 times in the test suite suggests this function is in a validation loop where users may enter multiple invalid paths before succeeding. The optimization particularly benefits workflows with: - Multiple path validation attempts (common in CLI prompts) - Batch operations validating many paths - Integration tests that exercise the prompt repeatedly The test results confirm this: single-path tests show 9-10x speedup, while tests with 50-100 retries show 3-4x speedup, demonstrating scalability benefits for both quick validations and extended retry scenarios. --- codeflash/cli_cmds/init_java.py | 10 +++++++--- codeflash/code_utils/code_utils.py | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/codeflash/cli_cmds/init_java.py b/codeflash/cli_cmds/init_java.py index 73822e626..a16a0a5d3 100644 --- a/codeflash/cli_cmds/init_java.py +++ b/codeflash/cli_cmds/init_java.py @@ -26,6 +26,8 @@ from codeflash.code_utils.shell_utils import get_shell_rc_path, is_powershell from codeflash.telemetry.posthog_cf import ph +_cached_theme = None + class JavaBuildTool(Enum): """Java build tools.""" @@ -57,9 +59,11 @@ class JavaSetupInfo: def _get_theme(): """Get the CodeflashTheme - imported lazily to avoid circular imports.""" - from codeflash.cli_cmds.cmd_init import CodeflashTheme - - return CodeflashTheme() + global _cached_theme + if _cached_theme is None: + from codeflash.cli_cmds.cmd_init import CodeflashTheme + _cached_theme = CodeflashTheme() + return _cached_theme def detect_java_build_tool(project_root: Path) -> JavaBuildTool: diff --git a/codeflash/code_utils/code_utils.py b/codeflash/code_utils/code_utils.py index 9244f6b11..36b9fb1f3 100644 --- a/codeflash/code_utils/code_utils.py +++ b/codeflash/code_utils/code_utils.py @@ -472,7 +472,8 @@ def validate_relative_directory_path(path: str) -> tuple[bool, str]: # Check for absolute paths, invalid characters, and validate path format error_msg = "" - if Path(path).is_absolute(): + # Use os.path.isabs() which is faster than Path().is_absolute() + if os.path.isabs(path): error_msg = "Path must be relative, not absolute" elif os.name == "nt": # Windows if any(char in _INVALID_CHARS_NT for char in path):