Skip to content

⚡️ Speed up function make_model_key by 22%#10

Open
codeflash-ai[bot] wants to merge 1 commit intomasterfrom
codeflash/optimize-make_model_key-mh4gij1b
Open

⚡️ Speed up function make_model_key by 22%#10
codeflash-ai[bot] wants to merge 1 commit intomasterfrom
codeflash/optimize-make_model_key-mh4gij1b

Conversation

@codeflash-ai
Copy link
Copy Markdown

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

📄 22% (0.22x) speedup for make_model_key in opendm/rollingshutter.py

⏱️ Runtime : 701 microseconds 576 microseconds (best of 369 runs)

📝 Explanation and details

The optimization achieves a 21% speedup by making two key changes to string processing:

1. String formatting optimization: Replaced the older "%s %s" % (make.strip(), model.strip()) format with an f-string f"{make.strip()} {model.strip()}". F-strings are faster because they avoid the overhead of tuple creation and the % operator's formatting machinery.

2. Eliminated redundant .strip() call: The original code called .strip() twice - once on the formatted string and once after .lower(). Since the f-string construction doesn't introduce any leading/trailing whitespace, the final .strip() was redundant. The optimized version moves .strip() to before .lower(), eliminating one unnecessary string operation.

The performance gains are consistent across all test cases, showing 7-31% improvements with the best results on:

  • Mixed case inputs (24-30% faster) - benefits most from f-string efficiency
  • Long strings with whitespace (19-29% faster) - benefits from eliminating the redundant strip
  • Unicode characters (15-30% faster) - f-strings handle unicode more efficiently

The optimization maintains identical functionality while reducing both string formatting overhead and unnecessary string operations, making it particularly effective for camera make/model processing where these operations happen frequently.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 2325 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
import pytest  # used for our unit tests
from opendm.rollingshutter import make_model_key

# unit tests

# 1. Basic Test Cases

def test_basic_normal_strings():
    # Basic: Normal make/model
    codeflash_output = make_model_key("Canon", "EOS 5D") # 907ns -> 739ns (22.7% faster)
    codeflash_output = make_model_key("Nikon", "D850") # 401ns -> 373ns (7.51% faster)
    codeflash_output = make_model_key("Sony", "Alpha 7R III") # 373ns -> 312ns (19.6% faster)

def test_basic_leading_trailing_spaces():
    # Basic: Leading/trailing spaces
    codeflash_output = make_model_key("  Canon  ", "  EOS 5D  ") # 1.01μs -> 862ns (16.9% faster)
    codeflash_output = make_model_key(" Nikon", "D850 ") # 488ns -> 449ns (8.69% faster)

def test_basic_mixed_case():
    # Basic: Mixed case input
    codeflash_output = make_model_key("CaNoN", "eOs 5d") # 784ns -> 629ns (24.6% faster)
    codeflash_output = make_model_key("SONY", "alpha 7r III") # 461ns -> 358ns (28.8% faster)

def test_basic_empty_strings():
    # Basic: Empty strings
    codeflash_output = make_model_key("", "") # 925ns -> 761ns (21.6% faster)
    codeflash_output = make_model_key("Canon", "") # 578ns -> 523ns (10.5% faster)
    codeflash_output = make_model_key("", "EOS 5D") # 470ns -> 422ns (11.4% faster)

def test_basic_spaces_only():
    # Basic: Spaces only
    codeflash_output = make_model_key("   ", "   ") # 810ns -> 757ns (7.00% faster)
    codeflash_output = make_model_key("Canon", "   ") # 560ns -> 529ns (5.86% faster)
    codeflash_output = make_model_key("   ", "EOS 5D") # 479ns -> 425ns (12.7% faster)

# 2. Edge Test Cases

def test_edge_special_characters():
    # Edge: Special characters in make/model
    codeflash_output = make_model_key("C@n0n", "E0$ 5D!") # 786ns -> 627ns (25.4% faster)
    codeflash_output = make_model_key("Nikon", "D850#") # 403ns -> 348ns (15.8% faster)
    codeflash_output = make_model_key("Leica", "M10-P*") # 325ns -> 275ns (18.2% faster)

def test_edge_unicode_characters():
    # Edge: Unicode characters
    codeflash_output = make_model_key("Fujifilm", "X-T4™") # 1.69μs -> 1.30μs (30.1% faster)
    codeflash_output = make_model_key("Олимпус", "OM-D E-M1") # 862ns -> 756ns (14.0% faster)
    codeflash_output = make_model_key("佳能", "EOS 5D") # 602ns -> 550ns (9.45% faster)

def test_edge_whitespace_variations():
    # Edge: Tabs, newlines, multiple spaces
    codeflash_output = make_model_key("Canon\t", "\nEOS 5D") # 951ns -> 818ns (16.3% faster)
    codeflash_output = make_model_key("  Canon  ", "EOS    5D") # 589ns -> 559ns (5.37% faster)
    codeflash_output = make_model_key("  ", "\t\n") # 586ns -> 473ns (23.9% faster)

def test_edge_extremely_long_strings():
    # Edge: Very long make/model strings
    long_make = "A" * 500
    long_model = "B" * 500
    expected = ("a" * 500) + " " + ("b" * 500)
    codeflash_output = make_model_key(long_make, long_model) # 1.61μs -> 1.35μs (19.6% faster)

def test_edge_make_model_with_only_whitespace():
    # Edge: Only whitespace in make/model
    codeflash_output = make_model_key("   ", "") # 934ns -> 752ns (24.2% faster)
    codeflash_output = make_model_key("", "   ") # 418ns -> 392ns (6.63% faster)
    codeflash_output = make_model_key("   ", "EOS 5D") # 537ns -> 470ns (14.3% faster)
    codeflash_output = make_model_key("Canon", "   ") # 457ns -> 402ns (13.7% faster)

def test_edge_make_model_with_numbers():
    # Edge: Make/model with numbers
    codeflash_output = make_model_key("Canon123", "EOS 5D") # 841ns -> 654ns (28.6% faster)
    codeflash_output = make_model_key("123", "456") # 472ns -> 414ns (14.0% faster)

def test_edge_make_model_with_multiple_spaces_between_words():
    # Edge: Multiple spaces between words
    codeflash_output = make_model_key("Canon  Inc", "EOS   5D") # 783ns -> 625ns (25.3% faster)

def test_edge_make_model_with_empty_and_nonempty():
    # Edge: One empty, one non-empty
    codeflash_output = make_model_key("", "D850") # 852ns -> 698ns (22.1% faster)
    codeflash_output = make_model_key("Nikon", "") # 593ns -> 471ns (25.9% faster)

# 3. Large Scale Test Cases

def test_large_scale_many_different_inputs():
    # Large Scale: Test with many different combinations
    for i in range(1000):
        make = f"Make{i}"
        model = f"Model{i}"
        expected = f"make{i} model{i}"
        codeflash_output = make_model_key(make, model) # 275μs -> 223μs (23.1% faster)

def test_large_scale_long_strings_and_spaces():
    # Large Scale: Long strings with spaces
    for i in range(10):
        make = "A" * 100 + "   "
        model = "B" * 100 + "   "
        expected = ("a" * 100) + " " + ("b" * 100)
        codeflash_output = make_model_key(make, model) # 4.94μs -> 3.99μs (23.9% faster)

def test_large_scale_varied_whitespace():
    # Large Scale: Varied whitespace in make/model
    for i in range(100):
        make = "  Make  " + " " * i
        model = "  Model  " + "\t" * (i % 10)
        expected = "make model"
        codeflash_output = make_model_key(make, model) # 36.1μs -> 30.5μs (18.4% faster)

def test_large_scale_unicode_and_special_chars():
    # Large Scale: Unicode and special chars
    for i in range(50):
        make = "Cámara" + chr(0x100 + i)
        model = "Modelo" + chr(0x200 + i)
        expected = f"cámara{chr(0x100 + i)} modelo{chr(0x200 + i)}"
        codeflash_output = make_model_key(make, model) # 19.0μs -> 16.5μs (15.3% faster)

def test_large_scale_empty_and_whitespace():
    # Large Scale: Many empty/whitespace inputs
    for i in range(100):
        make = " " * i
        model = " " * (100 - i)
        codeflash_output = make_model_key(make, model) # 36.6μs -> 30.6μs (19.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  # used for our unit tests
from opendm.rollingshutter import make_model_key

# unit tests

# ---------------------------
# 1. Basic Test Cases
# ---------------------------

def test_basic_typical_inputs():
    # Test with normal strings
    codeflash_output = make_model_key("Canon", "EOS 5D") # 962ns -> 732ns (31.4% faster)
    codeflash_output = make_model_key("Nikon", "D850") # 394ns -> 351ns (12.3% faster)
    codeflash_output = make_model_key("Sony", "Alpha 7 II") # 370ns -> 302ns (22.5% faster)

def test_basic_leading_trailing_spaces():
    # Test with leading/trailing spaces
    codeflash_output = make_model_key("  Canon", "EOS 5D  ") # 994ns -> 823ns (20.8% faster)
    codeflash_output = make_model_key("   Nikon   ", "   D850   ") # 518ns -> 505ns (2.57% faster)

def test_basic_mixed_case():
    # Test with mixed case input
    codeflash_output = make_model_key("CaNoN", "eOs 5D") # 800ns -> 617ns (29.7% faster)
    codeflash_output = make_model_key("SONY", "ALPHA 7 II") # 451ns -> 408ns (10.5% faster)

def test_basic_empty_strings():
    # Test with empty strings
    codeflash_output = make_model_key("", "") # 927ns -> 723ns (28.2% faster)
    codeflash_output = make_model_key("Canon", "") # 583ns -> 503ns (15.9% faster)
    codeflash_output = make_model_key("", "EOS 5D") # 479ns -> 402ns (19.2% faster)

# ---------------------------
# 2. Edge Test Cases
# ---------------------------

def test_edge_only_spaces():
    # Test with strings containing only spaces
    codeflash_output = make_model_key("   ", "   ") # 875ns -> 737ns (18.7% faster)
    codeflash_output = make_model_key("Canon", "   ") # 589ns -> 504ns (16.9% faster)
    codeflash_output = make_model_key("   ", "EOS 5D") # 483ns -> 399ns (21.1% faster)

def test_edge_special_characters():
    # Test with special characters in make/model
    codeflash_output = make_model_key("C@non", "E#S 5D") # 748ns -> 580ns (29.0% faster)
    codeflash_output = make_model_key("Ni!kon", "D850*") # 435ns -> 385ns (13.0% faster)

def test_edge_numbers_and_symbols():
    # Test with numbers and symbols
    codeflash_output = make_model_key("123", "456") # 768ns -> 612ns (25.5% faster)
    codeflash_output = make_model_key("Canon", "5D Mark IV") # 499ns -> 432ns (15.5% faster)

def test_edge_unicode_characters():
    # Test with unicode characters
    codeflash_output = make_model_key("Cañón", "ÉOS 5D") # 1.50μs -> 1.20μs (25.5% faster)
    codeflash_output = make_model_key("ソニー", "アルファ7") # 1.08μs -> 1.06μs (1.03% faster)

def test_edge_newline_and_tab_characters():
    # Test with newline and tab characters
    codeflash_output = make_model_key("Canon\n", "\tEOS 5D") # 946ns -> 838ns (12.9% faster)
    codeflash_output = make_model_key("\nNikon", "D850\t") # 501ns -> 486ns (3.09% faster)

def test_edge_make_or_model_none():
    # Test with None as input, should raise AttributeError
    with pytest.raises(AttributeError):
        make_model_key(None, "EOS 5D") # 1.25μs -> 1.21μs (3.65% faster)
    with pytest.raises(AttributeError):
        make_model_key("Canon", None) # 812ns -> 879ns (7.62% slower)
    with pytest.raises(AttributeError):
        make_model_key(None, None) # 594ns -> 602ns (1.33% slower)

def test_edge_make_or_model_not_string():
    # Test with non-string types, should raise AttributeError
    with pytest.raises(AttributeError):
        make_model_key(123, "EOS 5D") # 996ns -> 987ns (0.912% faster)
    with pytest.raises(AttributeError):
        make_model_key("Canon", 456) # 721ns -> 782ns (7.80% slower)
    with pytest.raises(AttributeError):
        make_model_key(123, 456) # 509ns -> 557ns (8.62% slower)

def test_edge_model_with_internal_spaces():
    # Model with multiple internal spaces
    codeflash_output = make_model_key("Canon", "  EOS   5D  ") # 1.03μs -> 846ns (21.5% faster)

def test_edge_make_and_model_are_same():
    # Make and model are identical
    codeflash_output = make_model_key("Canon", "Canon") # 823ns -> 645ns (27.6% faster)

# ---------------------------
# 3. Large Scale Test Cases
# ---------------------------

def test_large_scale_many_different_inputs():
    # Test with 1000 different makes/models
    for i in range(1000):
        make = f"Make{i}"
        model = f"Model{i}"
        expected = f"make{i} model{i}"
        codeflash_output = make_model_key(make, model) # 275μs -> 224μs (22.3% faster)

def test_large_scale_long_strings():
    # Test with very long make/model strings
    make = "Canon" * 200  # 1000+ chars
    model = "EOS5D" * 200
    expected = (make + " " + model).lower()
    codeflash_output = make_model_key(make, model) # 2.00μs -> 1.56μs (28.6% faster)

def test_large_scale_long_strings_with_spaces():
    # Long strings with leading/trailing spaces
    make = " " * 50 + "Canon" * 100 + " " * 50
    model = " " * 50 + "EOS5D" * 100 + " " * 50
    expected = ("canon" * 100 + " " + "eos5d" * 100).lower()
    codeflash_output = make_model_key(make, model) # 2.01μs -> 1.87μs (7.31% faster)

def test_large_scale_all_spaces():
    # Long strings of only spaces
    make = " " * 500
    model = " " * 500
    codeflash_output = make_model_key(make, model) # 1.47μs -> 1.28μs (14.6% faster)

def test_large_scale_special_unicode():
    # Large scale unicode input
    make = "ñ" * 500
    model = "é" * 500
    expected = ("ñ" * 500 + " " + "é" * 500).lower()
    codeflash_output = make_model_key(make, model) # 3.59μs -> 3.02μs (19.1% 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-make_model_key-mh4gij1b and push.

Codeflash

The optimization achieves a 21% speedup by making two key changes to string processing:

**1. String formatting optimization**: Replaced the older `"%s %s" % (make.strip(), model.strip())` format with an f-string `f"{make.strip()} {model.strip()}"`. F-strings are faster because they avoid the overhead of tuple creation and the `%` operator's formatting machinery.

**2. Eliminated redundant `.strip()` call**: The original code called `.strip()` twice - once on the formatted string and once after `.lower()`. Since the f-string construction doesn't introduce any leading/trailing whitespace, the final `.strip()` was redundant. The optimized version moves `.strip()` to before `.lower()`, eliminating one unnecessary string operation.

The performance gains are consistent across all test cases, showing **7-31% improvements** with the best results on:
- Mixed case inputs (24-30% faster) - benefits most from f-string efficiency
- Long strings with whitespace (19-29% faster) - benefits from eliminating the redundant strip
- Unicode characters (15-30% faster) - f-strings handle unicode more efficiently

The optimization maintains identical functionality while reducing both string formatting overhead and unnecessary string operations, making it particularly effective for camera make/model processing where these operations happen frequently.
@codeflash-ai codeflash-ai Bot requested a review from mashraf-222 October 24, 2025 06:15
@codeflash-ai codeflash-ai Bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Oct 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