Skip to content

Conversation

@codeflash-ai
Copy link
Contributor

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

⚡️ This pull request contains optimizations for PR #1199

If you approve this dependent PR, these changes will be merged into the original PR branch omni-java.

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


📄 365% (3.65x) speedup for _prompt_custom_directory in codeflash/cli_cmds/init_java.py

⏱️ Runtime : 101 milliseconds 21.7 milliseconds (best of 54 runs)

📝 Explanation and details

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.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 143 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Click to see Generated Regression Tests
import os
# imports
import sys
from pathlib import Path
from unittest.mock import patch

# Import real dependencies used by the function under test (CRITICAL: use the real modules)
import click
import inquirer
import pytest  # used for our unit tests
from codeflash.cli_cmds.cli_common import apologize_and_exit
from codeflash.cli_cmds.console import console
from codeflash.cli_cmds.init_java import _prompt_custom_directory
from codeflash.code_utils.code_utils import validate_relative_directory_path

def test_returns_valid_path_first_try():
    """
    Basic:
    - Ensure that when inquirer.prompt returns a valid path on the first attempt,
      the function returns that path as a string.
    """
    # Patch inquirer.prompt to simulate the user's input: a simple relative directory name.
    with patch.object(inquirer, "prompt", return_value={"custom_path": "src"}):
        codeflash_output = _prompt_custom_directory("project"); result = codeflash_output # 265μs -> 25.7μs (932% faster)

def test_returns_valid_path_when_prompt_returns_pathlib_object():
    """
    Basic:
    - Ensure the function properly stringifies objects such as pathlib.Path returned
      by inquirer.prompt and returns the string form.
    """
    with patch.object(inquirer, "prompt", return_value={"custom_path": Path("mydir")}):
        codeflash_output = _prompt_custom_directory("module"); result = codeflash_output # 270μs -> 28.0μs (868% faster)

def test_exits_on_user_cancellation_with_none():
    """
    Edge:
    - When inquirer.prompt returns None (user cancelled), the function should call
      apologize_and_exit() which exits the process. We assert that a SystemExit is raised.
    """
    # inquirer.prompt returns None to simulate user pressing Ctrl+C or cancelling the prompt
    with patch.object(inquirer, "prompt", return_value=None):
        with pytest.raises(SystemExit):
            _prompt_custom_directory("config")

def test_exits_on_user_cancellation_with_empty_dict():
    """
    Edge:
    - When inquirer.prompt returns an empty dict (falsy), the function should treat this
      as cancellation and call apologize_and_exit (=> SystemExit).
    """
    with patch.object(inquirer, "prompt", return_value={}):
        with pytest.raises(SystemExit):
            _prompt_custom_directory("data")

def test_invalid_then_valid_flow_prints_error_and_prompts_again(capsys):
    """
    Edge:
    - Simulate a user entering an invalid path first (containing '..' which validate rejects),
      then a valid path. The function should print an 'Invalid path:' message and then accept the
      valid path on the second attempt.
    """
    # First return an invalid path containing '..' (always invalid per validate_relative_directory_path),
    # then return a valid path.
    side_effects = [
        {"custom_path": "../secrets"},  # invalid - contains '..'
        {"custom_path": "valid_dir"},   # valid
    ]
    with patch.object(inquirer, "prompt", side_effect=side_effects):
        codeflash_output = _prompt_custom_directory("project"); result = codeflash_output

    # Capture the printed output to ensure that the invalid path message was shown.
    captured = capsys.readouterr()

def test_empty_string_path_is_rejected_and_prompts_again(capsys):
    """
    Edge:
    - If the user enters an empty string for the path, validate_relative_directory_path
      should reject it. The function should continue prompting until a valid path is provided.
    """
    side_effects = [
        {"custom_path": ""},          # invalid (empty)
        {"custom_path": "   "},       # invalid (whitespace only)
        {"custom_path": "valid_dir"}, # finally valid
    ]
    with patch.object(inquirer, "prompt", side_effect=side_effects):
        codeflash_output = _prompt_custom_directory("dir"); result = codeflash_output

    captured = capsys.readouterr()

def test_invalid_path_with_null_character_shows_error(capsys):
    """
    Edge:
    - Paths containing NUL ('\0') are invalid on Unix-like systems and the validator
      will reject them. Ensure the function prints an invalid path message and keeps prompting.
    - We simulate one invalid (contains '\0') and then a valid path.
    """
    # Compose a string that contains a null character which is invalid on Unix-like per validator.
    invalid_with_null = "bad\0path"
    side_effects = [
        {"custom_path": invalid_with_null},
        {"custom_path": "ok_dir"},
    ]
    with patch.object(inquirer, "prompt", side_effect=side_effects):
        codeflash_output = _prompt_custom_directory("assets"); result = codeflash_output

    captured = capsys.readouterr()

def test_many_invalid_attempts_then_valid(benchmark=None):
    """
    Large Scale:
    - Simulate many (but not more than 1000) invalid user attempts to ensure the loop
      remains stable and eventually returns the valid path.
    - We use 50 invalid attempts which is a stress test without being excessive.
    """
    num_invalid = 50  # well below the 1000 limit
    # Each invalid attempt uses a path containing '..' to ensure rejection
    invalid_attempts = [{"custom_path": f"bad_path_{i}/.."} for i in range(num_invalid)]
    # Final valid attempt
    invalid_attempts.append({"custom_path": "final_valid_dir"})

    with patch.object(inquirer, "prompt", side_effect=invalid_attempts):
        codeflash_output = _prompt_custom_directory("large"); result = codeflash_output # 16.0ms -> 4.19ms (281% faster)

def test_mixed_invalid_types_then_valid(capsys):
    """
    Large/Edge mix:
    - Simulate mixed invalid entries: absolute paths, traversal attempts, empty, and finally valid.
      This ensures the validator rejects a variety of invalid forms and the prompt loops correctly.
    """
    # Absolute path: use an absolute path in a cross-platform way by using Path.cwd()
    absolute = str(Path.cwd().resolve())
    side_effects = [
        {"custom_path": absolute},    # absolute path - should be rejected
        {"custom_path": "../hack"},   # traversal - rejected
        {"custom_path": ""},          # empty - rejected
        {"custom_path": "good_dir"},  # valid
    ]
    with patch.object(inquirer, "prompt", side_effect=side_effects):
        codeflash_output = _prompt_custom_directory("workspace"); result = codeflash_output

    captured = capsys.readouterr()

def test_validator_rejects_traversal_directly():
    """
    Sanity check for validate_relative_directory_path to ensure we rely on known behavior:
    - '..' should be rejected.
    """
    ok, msg = validate_relative_directory_path("..")

def test_validator_accepts_simple_relative_path():
    """
    Sanity check for validate_relative_directory_path that a simple relative path is accepted.
    """
    ok, msg = validate_relative_directory_path("some/relative/path")

def test_prompt_does_not_modify_input_objects():
    """
    Ensure that when a mutable object (like Path) is provided by the prompt, the function
    does not mutate the original object (we ensure the original remains intact).
    """
    original = Path("unchanged_dir")
    # Keep a copy for comparison
    original_str = str(original)
    with patch.object(inquirer, "prompt", return_value={"custom_path": original}):
        codeflash_output = _prompt_custom_directory("config"); result = codeflash_output # 268μs -> 25.7μs (943% faster)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
import sys
from unittest.mock import MagicMock, patch

import pytest
from codeflash.cli_cmds.init_java import _prompt_custom_directory
from codeflash.code_utils.code_utils import validate_relative_directory_path

def test_basic_valid_relative_path():
    """Test that a valid relative path is accepted and returned."""
    # Mock inquirer.prompt to return a valid relative path
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "tests"}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 271μs -> 25.2μs (978% faster)

def test_basic_valid_nested_path():
    """Test that a valid nested relative path is accepted."""
    # Mock inquirer.prompt to return a nested relative path
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "src/app/main"}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 272μs -> 26.5μs (927% faster)

def test_basic_single_directory_name():
    """Test that a single directory name is accepted."""
    # Mock inquirer.prompt to return a single directory name
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "config"}
        codeflash_output = _prompt_custom_directory("configuration"); result = codeflash_output # 265μs -> 24.4μs (990% faster)

def test_basic_dir_type_parameter_used():
    """Test that the dir_type parameter is used in the prompt message."""
    # Mock inquirer.prompt to verify the message contains dir_type
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "tests"}
        _prompt_custom_directory("custom_type") # 266μs -> 24.1μs (1003% faster)
        # Verify the prompt was called with correct arguments
        call_args = mock_prompt.call_args
        questions = call_args[0][0]

def test_basic_path_with_underscores():
    """Test that paths with underscores are accepted."""
    # Underscores are valid in directory names
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "test_data_files"}
        codeflash_output = _prompt_custom_directory("data"); result = codeflash_output # 264μs -> 24.3μs (988% faster)

def test_basic_path_with_hyphens():
    """Test that paths with hyphens are accepted."""
    # Hyphens are valid in directory names
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "test-data-files"}
        codeflash_output = _prompt_custom_directory("data"); result = codeflash_output # 263μs -> 23.9μs (1006% faster)

def test_basic_path_with_numbers():
    """Test that paths with numbers are accepted."""
    # Numbers are valid in directory names
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "test123/data456"}
        codeflash_output = _prompt_custom_directory("data"); result = codeflash_output # 265μs -> 25.8μs (928% faster)

def test_edge_path_with_leading_whitespace():
    """Test that paths with leading whitespace are trimmed and accepted."""
    # Whitespace should be stripped by validate_relative_directory_path
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "  tests"}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 285μs -> 27.3μs (948% faster)

def test_edge_path_traversal_attack_double_dot():
    """Test that path traversal attempts with '..' are rejected."""
    # Mock inquirer.prompt to return invalid path on first try, valid on second
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.side_effect = [
            {"custom_path": "../sensitive"},
            {"custom_path": "tests"}
        ]
        with patch('codeflash.cli_cmds.init_java.click.echo') as mock_echo:
            codeflash_output = _prompt_custom_directory("source"); result = codeflash_output

def test_edge_absolute_path_unix_style():
    """Test that absolute paths (Unix style) are rejected."""
    # Mock inquirer.prompt to return absolute path on first try, valid on second
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.side_effect = [
            {"custom_path": "/absolute/path"},
            {"custom_path": "relative/path"}
        ]
        with patch('codeflash.cli_cmds.init_java.click.echo') as mock_echo:
            codeflash_output = _prompt_custom_directory("source"); result = codeflash_output

def test_edge_absolute_path_windows_style():
    """Test that absolute paths (Windows style) are rejected."""
    # Mock inquirer.prompt to return Windows absolute path, then valid path
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.side_effect = [
            {"custom_path": "C:\\Users\\test"},
            {"custom_path": "relative/path"}
        ]
        with patch('codeflash.cli_cmds.init_java.click.echo') as mock_echo:
            codeflash_output = _prompt_custom_directory("source"); result = codeflash_output

def test_edge_empty_string_path():
    """Test that empty string paths are rejected."""
    # Mock inquirer.prompt to return empty string, then valid path
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.side_effect = [
            {"custom_path": ""},
            {"custom_path": "tests"}
        ]
        with patch('codeflash.cli_cmds.init_java.click.echo') as mock_echo:
            codeflash_output = _prompt_custom_directory("source"); result = codeflash_output

def test_edge_whitespace_only_path():
    """Test that paths with only whitespace are rejected."""
    # Mock inquirer.prompt to return whitespace-only path, then valid path
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.side_effect = [
            {"custom_path": "   "},
            {"custom_path": "tests"}
        ]
        with patch('codeflash.cli_cmds.init_java.click.echo') as mock_echo:
            codeflash_output = _prompt_custom_directory("source"); result = codeflash_output

def test_edge_multiple_invalid_attempts_before_valid():
    """Test that multiple invalid attempts are retried until valid path is given."""
    # Mock inquirer.prompt to return multiple invalid paths, then valid
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.side_effect = [
            {"custom_path": "../bad"},
            {"custom_path": "/absolute"},
            {"custom_path": ""},
            {"custom_path": "valid/path"}
        ]
        with patch('codeflash.cli_cmds.init_java.click.echo') as mock_echo:
            codeflash_output = _prompt_custom_directory("source"); result = codeflash_output

def test_edge_pathlib_path_object():
    """Test that pathlib.Path objects are handled correctly."""
    # The function receives the result and converts to string
    from pathlib import Path
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        path_obj = Path("tests/data")
        mock_prompt.return_value = {"custom_path": path_obj}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 269μs -> 25.9μs (939% faster)

def test_edge_unicode_in_path():
    """Test that unicode characters in paths are handled."""
    # Unicode characters may be valid depending on OS
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        # Using valid unicode directory names
        mock_prompt.return_value = {"custom_path": "tests_データ"}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 264μs -> 24.6μs (976% faster)

def test_edge_dot_directory_current():
    """Test that current directory reference '.' is handled."""
    # Single dot represents current directory and is a valid relative path
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "."}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 264μs -> 24.1μs (999% faster)

def test_edge_double_slash_in_path():
    """Test that paths with double slashes are handled."""
    # Double slashes should be accepted as valid path syntax
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "tests//data"}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 269μs -> 25.6μs (953% faster)

def test_edge_backslash_path_separator():
    """Test that backslash path separators are handled on all platforms."""
    # Windows-style separators should be accepted
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "tests\\data"}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 265μs -> 23.9μs (1011% faster)

def test_edge_mixed_slash_separators():
    """Test that mixed slash separators are handled."""
    # Mixed separators may appear and should be handled
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "tests/data\\nested/file"}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 265μs -> 25.1μs (957% faster)

def test_edge_dot_prefix_in_filename():
    """Test that dot-prefixed filenames/directories are accepted."""
    # Dot-prefixed names are valid (hidden files on Unix)
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": ".hidden/tests"}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 269μs -> 25.3μs (967% faster)

def test_edge_very_long_path_name():
    """Test that very long path names are handled."""
    # Create a long but valid relative path
    long_path = "/".join(["dir" + str(i) for i in range(50)])
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": long_path}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 295μs -> 47.5μs (522% faster)

def test_edge_error_message_shown_on_invalid_path():
    """Test that error messages are shown for invalid paths."""
    # Verify that click.echo is called with error message
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.side_effect = [
            {"custom_path": "../invalid"},
            {"custom_path": "valid"}
        ]
        with patch('codeflash.cli_cmds.init_java.click.echo') as mock_echo:
            _prompt_custom_directory("source")
            # Check that error message contains "Invalid path:"
            error_calls = [call[0][0] for call in mock_echo.call_args_list 
                          if "Invalid path:" in str(call[0][0])]

def test_edge_console_print_called():
    """Test that console.print is called after showing error."""
    # Verify formatting function is called
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        with patch('codeflash.cli_cmds.init_java.console.print') as mock_print:
            mock_prompt.side_effect = [
                {"custom_path": "../bad"},
                {"custom_path": "valid"}
            ]
            _prompt_custom_directory("source")

def test_large_many_retry_cycles():
    """Test that function handles many retry cycles efficiently."""
    # Generate 100 invalid paths, then 1 valid path
    invalid_paths = [
        {"custom_path": f"../{i}"} if i % 2 == 0 else {"custom_path": f"/{i}"}
        for i in range(100)
    ]
    invalid_paths.append({"custom_path": "valid_path"})
    
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.side_effect = invalid_paths
        with patch('codeflash.cli_cmds.init_java.click.echo'):
            codeflash_output = _prompt_custom_directory("source"); result = codeflash_output

def test_large_deeply_nested_path():
    """Test that deeply nested paths with many levels are handled."""
    # Create a path with 200 nested directories
    deep_path = "/".join([f"level{i:03d}" for i in range(200)])
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": deep_path}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 394μs -> 98.8μs (300% faster)

def test_large_path_with_many_special_chars():
    """Test that paths with many allowed special characters are handled."""
    # Create path with various valid special characters
    special_path = "test-data_v1.0/sub_dir-2/file_3.0/nested-test_data"
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": special_path}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 276μs -> 27.3μs (913% faster)

def test_large_repeated_prompts_same_invalid_path():
    """Test that the same invalid path can be entered multiple times and retried."""
    # User enters same invalid path multiple times
    invalid_path_list = [{"custom_path": "../../../etc"} for _ in range(50)]
    invalid_path_list.append({"custom_path": "valid/final/path"})
    
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.side_effect = invalid_path_list
        with patch('codeflash.cli_cmds.init_java.click.echo'):
            codeflash_output = _prompt_custom_directory("source"); result = codeflash_output

def test_large_alternating_valid_invalid_paths():
    """Test that function properly validates alternating valid and invalid paths."""
    # Create alternating pattern of invalid then valid paths
    paths = []
    for i in range(50):
        # Invalid paths
        paths.append({"custom_path": f"../{i}"})
        # Valid paths (but not returned since invalid comes first)
        paths.append({"custom_path": f"test/path{i}"})
    
    # Add final valid path that will be returned
    paths.append({"custom_path": "final/valid/path"})
    
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.side_effect = paths
        with patch('codeflash.cli_cmds.init_java.click.echo'):
            codeflash_output = _prompt_custom_directory("source"); result = codeflash_output

def test_large_long_dir_type_string():
    """Test that very long dir_type strings are handled in prompts."""
    # Create a very long dir_type string
    long_dir_type = "a" * 500
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": "valid/path"}
        codeflash_output = _prompt_custom_directory(long_dir_type); result = codeflash_output # 269μs -> 25.9μs (943% faster)
        # Verify the long string was included in the message
        call_args = mock_prompt.call_args
        questions = call_args[0][0]

def test_large_path_validation_performance():
    """Test that path validation is efficient even with many checks."""
    # Generate 100 valid paths and ensure they're all accepted on first try
    valid_paths = [f"test{i}/data{i}" for i in range(100)]
    
    for path in valid_paths:
        with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
            mock_prompt.return_value = {"custom_path": path}
            codeflash_output = _prompt_custom_directory("source"); result = codeflash_output

def test_large_complex_nested_with_special_chars():
    """Test deeply nested paths with special characters throughout."""
    # Create a complex path with many levels and special characters
    complex_path = "/".join([f"dir-{i}_v{i%10}.{i%5}" for i in range(100)])
    with patch('codeflash.cli_cmds.init_java.inquirer.prompt') as mock_prompt:
        mock_prompt.return_value = {"custom_path": complex_path}
        codeflash_output = _prompt_custom_directory("source"); result = codeflash_output # 324μs -> 61.1μs (431% faster)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

To edit these changes git checkout codeflash/optimize-pr1199-2026-02-01T21.28.53 and push.

Codeflash

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-ai codeflash-ai bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label Feb 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant