Skip to content

⚡️ Speed up function _public_version by 29%#13

Open
codeflash-ai[bot] wants to merge 1 commit intoopt-attempt-2from
codeflash/optimize-_public_version-mjjgjbvz
Open

⚡️ Speed up function _public_version by 29%#13
codeflash-ai[bot] wants to merge 1 commit intoopt-attempt-2from
codeflash/optimize-_public_version-mjjgjbvz

Conversation

@codeflash-ai
Copy link
Copy Markdown

@codeflash-ai codeflash-ai Bot commented Dec 24, 2025

📄 29% (0.29x) speedup for _public_version in src/packaging/specifiers.py

⏱️ Runtime : 1.05 milliseconds 811 microseconds (best of 6 runs)

📝 Explanation and details

The optimization achieves a 29% speedup by adding a fast path for the common case where only the local parameter is modified—which is exactly how _public_version() calls __replace__().

Key optimization:

The optimized code checks if len(kwargs) == 1 and "local" in kwargs first, which is the dominant use case based on the function references showing _public_version() is called from version comparison operators (_compare_equal, _compare_less_than_equal, _compare_greater_than_equal). When this condition is true, the code:

  1. Validates only the local parameter instead of checking all 6 parameters (epoch, release, pre, post, dev, local)
  2. Directly copies the 5 unchanged attributes (_epoch, _release, _pre, _post, _dev) without any validation overhead
  3. Avoids 11 dictionary lookups (the original code does "key" in kwargs for each of 6 parameters, plus the subsequent kwargs["key"] access for local)

Performance impact from profiling:

  • The fast path executes for 4,493 out of 4,748 calls (~95% hit rate)
  • For these calls, __replace__ runtime drops from 31.1ms to 17.5ms (44% faster)
  • The overhead of the fast-path check (200ns) is negligible compared to the savings (13.6ms)

Why this works:
The function references show _public_version() is called in hot comparison paths within the specifiers module. Version comparisons are critical operations in dependency resolution, so even microsecond improvements per call compound significantly. The test results confirm this—versions with local segments see 19-47% speedup, with the largest gains when no actual replacement occurs (47% faster when local=None is already true).

The general path remains for edge cases where multiple parameters change, ensuring correctness while optimizing the 95% case.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 1803 Passed
⏪ Replay Tests 255 Passed
🔎 Concolic Coverage Tests 1 Passed
📊 Tests Coverage 100.0%
🌀 Click to see Generated Regression Tests
import pytest
from src.packaging.specifiers import _public_version
from src.packaging.version import Version

# ------------------ Basic Test Cases ------------------

def test_basic_removes_local_segment():
    # Test that local version segment is removed
    v = Version("1.2.3+abc")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.29μs -> 1.08μs (19.1% faster)

def test_basic_no_local_segment():
    # Test that version with no local segment is unchanged
    v = Version("1.2.3")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.04μs -> 708ns (47.0% faster)

def test_basic_pre_post_dev_local():
    # Test with pre, post, dev, and local segments
    v = Version("1.2.3a1.post2.dev3+xyz.10")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.33μs -> 1.12μs (18.5% faster)

def test_basic_post_release_local():
    # Test with post release and local
    v = Version("2.0.post1+build.5")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.46μs -> 1.12μs (29.6% faster)

def test_basic_epoch_and_local():
    # Test with epoch and local
    v = Version("1!2.3.4+abc")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.04μs (20.0% faster)

# ------------------ Edge Test Cases ------------------

def test_edge_local_with_numbers_and_letters():
    # Local segment with mixed numbers/letters
    v = Version("1.0.0+abc.123.def-456")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.21μs -> 1.08μs (11.5% faster)

def test_edge_local_uppercase():
    # Local segment with uppercase letters (should be normalized)
    v = Version("1.0.0+ABC.DEF")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.21μs -> 1.08μs (11.5% faster)

def test_edge_local_with_underscores_and_hyphens():
    # Local segment with underscores and hyphens
    v = Version("1.0.0+abc_def-ghi")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.21μs -> 1.04μs (16.1% faster)

def test_edge_local_only_digits():
    # Local segment with only digits
    v = Version("1.0.0+123.456")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.04μs (20.0% faster)

def test_edge_no_release_segment_local():
    # Edge: minimal release with local
    v = Version("0+local")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.21μs -> 1.08μs (11.4% faster)

def test_edge_multiple_local_segments():
    # Multiple local segments separated by various separators
    v = Version("1.2.3+one.two-three_four")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.04μs (20.1% faster)

def test_edge_local_segment_with_leading_zero():
    # Local segment with leading zeros
    v = Version("1.2.3+001.002")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.21μs -> 1.08μs (11.5% faster)

def test_edge_dev_pre_post_and_local():
    # All segments present
    v = Version("3.4.5rc2.post3.dev1+build123")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.08μs (15.4% faster)

def test_edge_local_segment_with_long_string():
    # Long local segment string
    local_str = "a" * 50
    v = Version(f"1.0.0+{local_str}")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.21μs -> 1.08μs (11.5% faster)

def test_edge_local_segment_with_special_chars():
    # Local with allowed special chars
    v = Version("1.0.0+abc-def_ghi.123")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.08μs (15.4% faster)

def test_edge_local_segment_with_mixed_case():
    # Local segment with mixed case
    v = Version("1.0.0+aBc.DeF")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.29μs -> 1.04μs (24.1% faster)

def test_edge_only_local_segment():
    # Version with only local segment (invalid per PEP440, but test for robustness)
    with pytest.raises(Exception):
        Version("+local")

# ------------------ Large Scale Test Cases ------------------

def test_large_scale_many_versions_removal():
    # Test many versions with local segments
    for i in range(100):
        v = Version(f"{i}.{i+1}.{i+2}+build{i}")
        codeflash_output = _public_version(v); pub_v = codeflash_output # 50.5μs -> 39.4μs (28.1% faster)

def test_large_scale_long_release_and_local():
    # Very long release segment and local segment
    release = ".".join(str(i) for i in range(20))
    local = ".".join(f"abc{i}" for i in range(20))
    v = Version(f"{release}+{local}")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.33μs -> 1.08μs (23.1% faster)

def test_large_scale_varied_segments():
    # Many versions with varied segments
    for i in range(50):
        v = Version(f"{i}.{i+1}.{i+2}a{i}.post{i}.dev{i}+build{i}")
        codeflash_output = _public_version(v); pub_v = codeflash_output # 26.5μs -> 20.4μs (29.6% faster)
        expected = f"{i}.{i+1}.{i+2}a{i}.post{i}.dev{i}"

def test_large_scale_max_local_segment():
    # Local segment with 1000 chars (max reasonable per instructions)
    local = "a" * 999
    v = Version(f"1.0.0+{local}")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.21μs -> 1.08μs (11.4% faster)

def test_large_scale_release_segment_length():
    # Release segment with 1000 elements (max allowed)
    release = ".".join(str(i) for i in range(1, 1001))
    v = Version(f"{release}+local")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 2.25μs -> 1.12μs (100% faster)

# ------------------ Mutation Safety ------------------

def test_mutation_safety_does_not_modify_original():
    # Ensure original Version object is not mutated
    v = Version("1.2.3+abc")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.21μs -> 1.08μs (11.5% faster)

def test_mutation_safety_idempotent_on_no_local():
    # If no local, should return same object (by __replace__ contract)
    v = Version("1.2.3")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 958ns -> 750ns (27.7% faster)

# ------------------ Determinism ------------------

def test_determinism_multiple_calls():
    # Multiple calls should yield same result
    v = Version("1.2.3+abc")
    codeflash_output = _public_version(v); pub_v1 = codeflash_output # 1.29μs -> 1.04μs (23.9% faster)
    codeflash_output = _public_version(v); pub_v2 = codeflash_output # 667ns -> 500ns (33.4% faster)

# ------------------ Error Handling ------------------

def test_error_invalid_version_string():
    # Should raise on invalid version string
    with pytest.raises(Exception):
        Version("not_a_version+abc")

def test_error_invalid_local_segment():
    # Should raise on invalid local segment (e.g. illegal chars)
    with pytest.raises(Exception):
        Version("1.0.0+@@@")

# ------------------ Docstring Example Test ------------------

def test_docstring_example():
    # Test example from docstring
    v1 = Version("1.0a5")
    v2 = Version("1.0")
    codeflash_output = _public_version(v1) # 1.12μs -> 750ns (50.0% faster)
    codeflash_output = _public_version(v2) # 542ns -> 375ns (44.5% faster)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
import pytest
from src.packaging.specifiers import _public_version
from src.packaging.version import Version

# ----------------------------
# Basic Test Cases
# ----------------------------

def test_basic_version_no_local():
    # Should return the same version object if no local version is present
    v = Version("1.2.3")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 917ns (36.3% faster)

def test_basic_version_with_local():
    # Should strip the local version segment
    v = Version("1.2.3+abc")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.62μs -> 1.50μs (8.33% faster)

def test_basic_pre_release_with_local():
    # Should strip local version from pre-release
    v = Version("1.2.3a1+local")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.62μs -> 1.42μs (14.8% faster)

def test_basic_post_release_with_local():
    # Should strip local version from post-release
    v = Version("1.2.3.post4+build")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.58μs -> 1.25μs (26.6% faster)

def test_basic_dev_release_with_local():
    # Should strip local version from dev-release
    v = Version("1.2.3.dev5+meta")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.54μs -> 1.17μs (32.0% faster)

def test_basic_all_segments_with_local():
    # Should strip local version from a version with all segments
    v = Version("2!1.2.3a1.post2.dev3+abc.def")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.54μs -> 1.17μs (32.1% faster)

def test_basic_all_segments_no_local():
    # Should not change a version with all segments but no local
    v = Version("2!1.2.3a1.post2.dev3")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.12μs -> 791ns (42.2% faster)

# ----------------------------
# Edge Test Cases
# ----------------------------

def test_edge_only_local():
    # A version with only local segment (invalid by PEP 440, but let's check)
    with pytest.raises(Exception):
        Version("+abc")

def test_edge_local_with_digits_and_letters():
    # Local segment with mixed digits and letters
    v = Version("1.0.0+abc.123.XYZ-foo_42")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.38μs -> 1.12μs (22.2% faster)

def test_edge_local_with_uppercase():
    # Local segment with uppercase letters should be normalized but stripped
    v = Version("1.0.0+ABC.DEF")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.21μs -> 1.12μs (7.47% faster)

def test_edge_epoch_and_local():
    # Epoch and local segment
    v = Version("3!1.2.3+build.99")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.08μs (15.3% faster)

def test_edge_pre_post_dev_and_local():
    # All segments present, including local
    v = Version("1.2.3rc1.post2.dev7+zzz")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.42μs -> 1.12μs (25.9% faster)

def test_edge_multiple_local_separators():
    # Local segment with multiple separators
    v = Version("1.0.0+abc-def_ghi.jkl")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.12μs (11.1% faster)

def test_edge_local_with_leading_zeroes():
    # Local segment with leading zeroes in number
    v = Version("1.0.0+foo.001")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.08μs (15.4% faster)

def test_edge_local_with_long_segment():
    # Local segment with a very long string
    long_local = "a" * 250
    v = Version(f"1.0.0+{long_local}")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.12μs (11.1% faster)

def test_edge_local_with_non_ascii():
    # Local segment with non-ascii should raise error
    with pytest.raises(Exception):
        Version("1.0.0+abc💩")

def test_edge_local_with_empty_string():
    # Local segment empty string is not valid, should raise error
    with pytest.raises(Exception):
        Version("1.0.0+")

def test_edge_local_with_only_digit():
    # Local segment with only digits
    v = Version("1.0.0+12345")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.12μs (11.1% faster)

def test_edge_local_with_only_separator():
    # Local segment with only separator is invalid
    with pytest.raises(Exception):
        Version("1.0.0+.")

def test_edge_no_release_segment():
    # No release segment is invalid
    with pytest.raises(Exception):
        Version("+abc")

def test_edge_release_zero_with_local():
    # Release zero with local segment
    v = Version("0+meta")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.29μs -> 1.08μs (19.2% faster)

def test_edge_release_with_leading_v_and_local():
    # Leading 'v' and local segment
    v = Version("v1.2.3+abc")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.25μs -> 1.08μs (15.4% faster)

# ----------------------------
# Large Scale Test Cases
# ----------------------------

def test_large_scale_many_versions():
    # Test with 1000 versions with local segments
    for i in range(1, 1001):
        v = Version(f"{i}.{i+1}.{i+2}+build{i}")
        codeflash_output = _public_version(v); pub_v = codeflash_output # 495μs -> 384μs (28.9% faster)

def test_large_scale_long_release_segment_with_local():
    # Release segment with many sub-parts and local segment
    release = ".".join(str(i) for i in range(1, 50))
    v = Version(f"{release}+abc")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.38μs -> 1.12μs (22.2% faster)

def test_large_scale_long_local_segment():
    # Local segment with many parts
    local = ".".join([f"part{i}" for i in range(1, 50)])
    v = Version(f"1.0.0+{local}")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.21μs -> 1.12μs (7.47% faster)

def test_large_scale_all_segments_with_long_local():
    # All segments present with long local segment
    local = ".".join([f"meta{i}" for i in range(1, 50)])
    v = Version(f"2!12.34.56a7.post8.dev9+{local}")
    codeflash_output = _public_version(v); pub_v = codeflash_output # 1.33μs -> 1.08μs (23.2% faster)

def test_large_scale_multiple_versions_with_varied_local():
    # 500 versions with varied local segments
    for i in range(1, 501):
        local = f"abc{i}.xyz{i*2}"
        v = Version(f"3.4.5+{local}")
        codeflash_output = _public_version(v); pub_v = codeflash_output # 246μs -> 190μs (29.3% faster)

def test_large_scale_many_pre_post_dev_with_local():
    # 100 versions with pre, post, dev, and local segments
    for i in range(1, 101):
        v = Version(f"1.2.3a{i}.post{i}.dev{i}+build{i}")
        codeflash_output = _public_version(v); pub_v = codeflash_output # 51.6μs -> 40.1μs (28.6% faster)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
from src.packaging.specifiers import _public_version
from src.packaging.version import Version

def test__public_version():
    _public_version(Version('0'))
⏪ Click to see Replay Tests
Test File::Test Function Original ⏱️ Optimized ⏱️ Speedup
test_benchmark_py__replay_test_0.py::test_src_packaging_specifiers__public_version 117μs 87.2μs 35.1%✅
🔎 Click to see Concolic Coverage Tests
Test File::Test Function Original ⏱️ Optimized ⏱️ Speedup
codeflash_concolic_ui1l843q/tmplb9r5ewz/test_concolic_coverage.py::test__public_version 2.08μs 2.00μs 4.15%✅

To edit these changes git checkout codeflash/optimize-_public_version-mjjgjbvz and push.

Codeflash Static Badge

The optimization achieves a **29% speedup** by adding a **fast path for the common case** where only the `local` parameter is modified—which is exactly how `_public_version()` calls `__replace__()`.

**Key optimization:**

The optimized code checks `if len(kwargs) == 1 and "local" in kwargs` first, which is the dominant use case based on the function references showing `_public_version()` is called from version comparison operators (`_compare_equal`, `_compare_less_than_equal`, `_compare_greater_than_equal`). When this condition is true, the code:

1. **Validates only the `local` parameter** instead of checking all 6 parameters (`epoch`, `release`, `pre`, `post`, `dev`, `local`)
2. **Directly copies the 5 unchanged attributes** (`_epoch`, `_release`, `_pre`, `_post`, `_dev`) without any validation overhead
3. **Avoids 11 dictionary lookups** (the original code does `"key" in kwargs` for each of 6 parameters, plus the subsequent `kwargs["key"]` access for `local`)

**Performance impact from profiling:**
- The fast path executes for **4,493 out of 4,748 calls** (~95% hit rate)
- For these calls, `__replace__` runtime drops from **31.1ms to 17.5ms** (44% faster)
- The overhead of the fast-path check (200ns) is negligible compared to the savings (13.6ms)

**Why this works:**
The function references show `_public_version()` is called in **hot comparison paths** within the specifiers module. Version comparisons are critical operations in dependency resolution, so even microsecond improvements per call compound significantly. The test results confirm this—versions with local segments see 19-47% speedup, with the largest gains when no actual replacement occurs (47% faster when `local=None` is already true).

The general path remains for edge cases where multiple parameters change, ensuring correctness while optimizing the 95% case.
@codeflash-ai codeflash-ai Bot requested a review from KRRT7 December 24, 2025 03:31
@codeflash-ai codeflash-ai Bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Dec 24, 2025
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 🎯 Quality: High Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants