Skip to content

⚡️ Speed up function parse_wnid by 45% - #7

Open
codeflash-ai[bot] wants to merge 1 commit into
mainfrom
codeflash/optimize-parse_wnid-mgqpw6yf
Open

⚡️ Speed up function parse_wnid by 45%#7
codeflash-ai[bot] wants to merge 1 commit into
mainfrom
codeflash/optimize-parse_wnid-mgqpw6yf

Conversation

@codeflash-ai

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

Copy link
Copy Markdown

📄 45% (0.45x) speedup for parse_wnid in src/spdl/source/imagenet.py

⏱️ Runtime : 161 microseconds 111 microseconds (best of 283 runs)

📝 Explanation and details

The optimization replaces the inline regex pattern compilation with a pre-compiled regex pattern stored in a module-level constant _WNID_RE = re.compile(r"n\d{8}").

Key optimization: Instead of recompiling the regex pattern r"n\d{8}" on every function call via re.search(), the pattern is compiled once at module import time and reused for all subsequent calls.

Why this is faster: Regex compilation is computationally expensive, involving pattern parsing, finite state machine construction, and optimization. The line profiler shows the regex search line dropped from 518,553ns to 156,941ns (70% reduction), explaining most of the 45% overall speedup.

Performance characteristics: The optimization provides consistent speedup across all test cases (28-76% faster), with particularly strong gains for:

  • Simple exact matches (56-70% faster)
  • Strings with early matches (65-76% faster)
  • Large strings where the WNID appears early (58-64% faster)

The speedup is less pronounced for cases requiring extensive string scanning (like large strings with WNID at the end or many invalid patterns), but still meaningful at 4-19% improvement. This optimization is especially beneficial for workloads with frequent WNID parsing calls.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 65 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 1 Passed
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
import re

# imports
import pytest  # used for our unit tests
from spdl.source.imagenet import parse_wnid

# unit tests

# --- Basic Test Cases ---

def test_basic_exact_match():
    # Test with a string that is exactly a valid WNID
    codeflash_output = parse_wnid("n01234567") # 1.91μs -> 1.23μs (56.1% faster)

def test_basic_embedded_match():
    # Test with a string containing WNID in the middle
    codeflash_output = parse_wnid("foo_n12345678_bar") # 2.06μs -> 1.29μs (60.2% faster)

def test_basic_multiple_wnids():
    # Test with a string containing multiple WNIDs, should return the first
    codeflash_output = parse_wnid("n11111111 and n22222222") # 1.96μs -> 1.15μs (70.2% faster)

def test_basic_leading_and_trailing_spaces():
    # Test with spaces around the WNID
    codeflash_output = parse_wnid("  n87654321  ") # 1.81μs -> 1.11μs (62.1% faster)

def test_basic_wnid_at_start():
    # WNID at the very start of the string
    codeflash_output = parse_wnid("n00000001 is the first") # 1.84μs -> 1.11μs (65.4% faster)

def test_basic_wnid_at_end():
    # WNID at the very end of the string
    codeflash_output = parse_wnid("This ends with n99999999") # 2.03μs -> 1.28μs (58.6% faster)

# --- Edge Test Cases ---

def test_edge_no_wnid():
    # Test with a string that does not contain a WNID
    with pytest.raises(ValueError):
        parse_wnid("no wnid here") # 2.27μs -> 1.56μs (45.5% faster)

def test_edge_empty_string():
    # Test with an empty string
    with pytest.raises(ValueError):
        parse_wnid("") # 1.87μs -> 1.17μs (59.7% faster)

def test_edge_wnid_with_wrong_prefix():
    # Test with a string that looks like a WNID but has wrong prefix
    with pytest.raises(ValueError):
        parse_wnid("x12345678") # 1.87μs -> 1.19μs (57.1% faster)

def test_edge_wnid_with_too_few_digits():
    # Test with a string with too few digits
    with pytest.raises(ValueError):
        parse_wnid("n1234567") # 1.84μs -> 1.12μs (64.4% faster)

def test_edge_wnid_with_too_many_digits():
    # Test with a string with too many digits
    codeflash_output = parse_wnid("n123456789") # 2.25μs -> 1.46μs (54.1% faster)

def test_edge_wnid_with_letters_in_digits():
    # Test with a string where digits contain letters
    with pytest.raises(ValueError):
        parse_wnid("n12a45678") # 2.19μs -> 1.48μs (48.1% faster)

def test_edge_wnid_with_special_chars():
    # Test with special characters around WNID
    codeflash_output = parse_wnid("@n12345678!") # 2.17μs -> 1.37μs (58.2% faster)

def test_edge_multiple_wnids_non_adjacent():
    # Test with multiple WNIDs separated by text
    codeflash_output = parse_wnid("start n11111111 middle n22222222 end") # 2.00μs -> 1.29μs (55.0% faster)

def test_edge_wnid_lowercase_only():
    # Test with lowercase 'n' only (should match)
    codeflash_output = parse_wnid("n12345678") # 1.94μs -> 1.21μs (60.8% faster)

def test_edge_wnid_uppercase_N():
    # Test with uppercase 'N' (should not match)
    with pytest.raises(ValueError):
        parse_wnid("N12345678") # 1.91μs -> 1.21μs (57.6% faster)

def test_edge_wnid_with_newline():
    # Test with WNID at start of a line after newline
    codeflash_output = parse_wnid("foo\nn87654321bar") # 2.05μs -> 1.21μs (69.8% faster)

def test_edge_wnid_with_tab():
    # Test with WNID after tab character
    codeflash_output = parse_wnid("\tn12345678") # 2.04μs -> 1.16μs (76.2% faster)

def test_edge_wnid_with_unicode():
    # Test with unicode characters before and after
    codeflash_output = parse_wnid("αβγn12345678δθ") # 2.98μs -> 2.11μs (41.0% faster)

# --- Large Scale Test Cases ---

def test_large_scale_many_wnids():
    # Test with a string containing many WNIDs, should return the first
    wnids = [f"n{str(i).zfill(8)}" for i in range(100)]
    s = " ".join(wnids)
    codeflash_output = parse_wnid(s) # 2.02μs -> 1.29μs (56.9% faster)

def test_large_scale_long_string_without_wnid():
    # Test with a large string that does NOT contain any WNID
    s = "x" * 999 + "y" * 999
    with pytest.raises(ValueError):
        parse_wnid(s) # 2.74μs -> 2.13μs (28.6% faster)

def test_large_scale_wnid_at_end_of_long_string():
    # Test with a large string and WNID at the very end
    s = "a" * 999 + "n12345678"
    codeflash_output = parse_wnid(s) # 2.48μs -> 1.60μs (55.1% faster)

def test_large_scale_wnid_at_start_of_long_string():
    # Test with a large string and WNID at the very start
    s = "n87654321" + "b" * 999
    codeflash_output = parse_wnid(s) # 2.03μs -> 1.28μs (58.4% faster)

def test_large_scale_wnid_in_middle_of_long_string():
    # Test with a large string and WNID in the middle
    s = "c" * 500 + "n13579246" + "d" * 499
    codeflash_output = parse_wnid(s) # 2.10μs -> 1.31μs (60.6% faster)

def test_large_scale_multiple_wnids_spaced_out():
    # Test with multiple WNIDs spaced far apart
    s = "x" * 200 + "n12345678" + "y" * 200 + "n87654321" + "z" * 200
    codeflash_output = parse_wnid(s) # 2.00μs -> 1.26μs (58.9% faster)

def test_large_scale_all_possible_digits():
    # Test with all possible digits in WNID
    codeflash_output = parse_wnid("n00000000") # 1.90μs -> 1.16μs (64.2% faster)
    codeflash_output = parse_wnid("n99999999") # 899ns -> 563ns (59.7% faster)

# --- Mutation Testing (Negative) ---

def test_mutation_no_leading_n():
    # Should not match if there is no leading 'n'
    with pytest.raises(ValueError):
        parse_wnid("12345678") # 1.99μs -> 1.18μs (67.8% faster)

def test_mutation_partial_match():
    # Should not match if there is a partial WNID
    with pytest.raises(ValueError):
        parse_wnid("n1234567") # 1.86μs -> 1.15μs (61.2% faster)

def test_mutation_match_first_only():
    # Should only return the first WNID, not the second
    s = "n11111111 n22222222"
    codeflash_output = parse_wnid(s) # 2.12μs -> 1.34μs (58.2% faster)

def test_mutation_case_sensitive_n():
    # Should not match uppercase 'N'
    with pytest.raises(ValueError):
        parse_wnid("N12345678") # 1.88μs -> 1.19μs (57.8% faster)

def test_mutation_match_not_too_many_digits():
    # Should match only first 8 digits after 'n'
    s = "n123456789"
    codeflash_output = parse_wnid(s) # 2.05μs -> 1.31μs (56.3% faster)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
import re

# imports
import pytest  # used for our unit tests
from spdl.source.imagenet import parse_wnid

# unit tests

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

def test_basic_valid_wnid_alone():
    # Test with a string containing only a valid WNID
    codeflash_output = parse_wnid("n01234567") # 2.11μs -> 1.34μs (57.2% faster)

def test_basic_valid_wnid_with_text_before():
    # Test with valid WNID preceded by text
    codeflash_output = parse_wnid("foo n12345678") # 2.07μs -> 1.29μs (60.1% faster)

def test_basic_valid_wnid_with_text_after():
    # Test with valid WNID followed by text
    codeflash_output = parse_wnid("n87654321 bar") # 2.06μs -> 1.24μs (66.1% faster)

def test_basic_valid_wnid_embedded():
    # Test with valid WNID embedded in text
    codeflash_output = parse_wnid("abc n99999999 xyz") # 2.02μs -> 1.24μs (63.3% faster)

def test_basic_multiple_wnids_returns_first():
    # Test with multiple WNIDs, should return the first
    codeflash_output = parse_wnid("n00000001 n00000002") # 1.99μs -> 1.19μs (66.8% faster)

def test_basic_wnid_with_leading_zeros():
    # Test with WNID containing leading zeros
    codeflash_output = parse_wnid("n00000000") # 1.93μs -> 1.18μs (63.3% faster)

def test_basic_wnid_with_trailing_newline():
    # Test with WNID and trailing newline
    codeflash_output = parse_wnid("n12345678\n") # 1.96μs -> 1.16μs (69.4% faster)

def test_basic_wnid_with_surrounding_whitespace():
    # Test with WNID surrounded by whitespace
    codeflash_output = parse_wnid("   n87654321   ") # 1.98μs -> 1.12μs (76.2% faster)

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

def test_edge_no_wnid_raises_valueerror():
    # Test with string containing no WNID
    with pytest.raises(ValueError):
        parse_wnid("no wnid here") # 2.37μs -> 1.55μs (52.6% faster)

def test_edge_empty_string_raises_valueerror():
    # Test with empty string
    with pytest.raises(ValueError):
        parse_wnid("") # 1.92μs -> 1.19μs (61.5% faster)

def test_edge_partial_wnid_too_short():
    # Test with partial WNID (too short)
    with pytest.raises(ValueError):
        parse_wnid("n1234567") # 1.90μs -> 1.14μs (67.3% faster)


def test_edge_wnid_with_letters_in_digits():
    # Test with WNID where digits contain letters
    with pytest.raises(ValueError):
        parse_wnid("n1234a678") # 2.78μs -> 1.87μs (48.8% faster)

def test_edge_wnid_with_uppercase_n():
    # Test with uppercase N, should not match
    with pytest.raises(ValueError):
        parse_wnid("N12345678") # 2.07μs -> 1.30μs (59.2% faster)

def test_edge_wnid_with_non_digit_characters():
    # Test with non-digit characters after n
    with pytest.raises(ValueError):
        parse_wnid("n1234x678") # 2.36μs -> 1.59μs (48.4% faster)

def test_edge_wnid_at_start_of_string():
    # Test with WNID at the very start of the string
    codeflash_output = parse_wnid("n12345678 and some text") # 2.37μs -> 1.59μs (49.2% faster)

def test_edge_wnid_at_end_of_string():
    # Test with WNID at the very end of the string
    codeflash_output = parse_wnid("some text n87654321") # 2.11μs -> 1.29μs (63.3% faster)

def test_edge_wnid_with_special_characters():
    # Test with special characters around WNID
    codeflash_output = parse_wnid("!n12345678?") # 2.00μs -> 1.28μs (56.2% faster)

def test_edge_multiple_wnids_with_noise():
    # Test with multiple WNIDs and noise between them
    codeflash_output = parse_wnid("n00000001--n00000002") # 1.90μs -> 1.17μs (63.3% faster)

def test_edge_wnid_with_tab_character():
    # Test WNID with tab character before it
    codeflash_output = parse_wnid("\tn12345678") # 1.95μs -> 1.23μs (58.1% faster)

def test_edge_wnid_with_unicode_characters():
    # Test WNID surrounded by unicode characters
    codeflash_output = parse_wnid("Ωn12345678β") # 3.00μs -> 2.23μs (34.5% faster)

def test_edge_wnid_with_multiple_lines():
    # Test WNID in multiline string
    codeflash_output = parse_wnid("line1\nn12345678\nline3") # 2.10μs -> 1.32μs (59.2% faster)

def test_edge_wnid_with_only_n_and_digits():
    # Test with string that is only 'n' and digits but not enough digits
    with pytest.raises(ValueError):
        parse_wnid("n1234") # 1.92μs -> 1.17μs (64.8% faster)

def test_edge_wnid_with_spaces_in_digits():
    # Test with spaces in the digits (should not match)
    with pytest.raises(ValueError):
        parse_wnid("n1234 5678") # 2.30μs -> 1.57μs (46.4% faster)

def test_edge_wnid_with_extra_characters_inside():
    # Test with extra characters inside WNID
    with pytest.raises(ValueError):
        parse_wnid("n12x345678") # 2.22μs -> 1.48μs (50.3% faster)

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

def test_large_many_wnids_returns_first():
    # Test with a long string containing many WNIDs, should return the first one
    wnids = [f"n{str(i).zfill(8)}" for i in range(100)]
    s = " ".join(wnids)
    codeflash_output = parse_wnid(s) # 2.37μs -> 1.45μs (63.8% faster)

def test_large_long_string_with_wnid_at_end():
    # Test with a long string and WNID at the end
    s = "a" * 500 + " n12345678"
    codeflash_output = parse_wnid(s) # 2.36μs -> 1.50μs (57.1% faster)

def test_large_long_string_with_wnid_at_start():
    # Test with a long string and WNID at the start
    s = "n87654321 " + "b" * 500
    codeflash_output = parse_wnid(s) # 1.97μs -> 1.22μs (61.5% faster)

def test_large_long_string_with_no_wnid():
    # Test with a long string with no WNID
    s = "x" * 1000
    with pytest.raises(ValueError):
        parse_wnid(s) # 2.46μs -> 1.68μs (46.2% faster)

def test_large_string_with_multiple_wnids_and_noise():
    # Test with a large string containing many WNIDs and random noise
    wnids = [f"n{str(i).zfill(8)}" for i in range(100)]
    noise = ["abc", "123", "!", " "]
    s = ""
    for i in range(100):
        s += wnids[i] + noise[i % len(noise)]
    codeflash_output = parse_wnid(s) # 2.32μs -> 1.47μs (58.3% faster)

def test_large_string_with_wnid_in_middle():
    # Test with a large string with WNID in the middle
    s = "x" * 400 + "n12345678" + "y" * 400
    codeflash_output = parse_wnid(s) # 2.19μs -> 1.44μs (51.4% faster)

def test_large_string_with_wnid_surrounded_by_many_non_matching_patterns():
    # Test with many similar but non-matching patterns
    s = " ".join([f"n{str(i).zfill(7)}" for i in range(100)]) + " n12345678"
    # All preceding patterns are too short, only last one matches
    codeflash_output = parse_wnid(s) # 5.17μs -> 4.34μs (19.0% faster)

def test_large_string_with_many_invalid_and_one_valid_wnid():
    # Test with many invalid WNIDs and one valid
    s = " ".join(["n1234567x" for _ in range(500)]) + " n87654321"
    codeflash_output = parse_wnid(s) # 16.5μs -> 15.8μs (4.35% faster)

def test_large_string_with_wnid_and_newlines():
    # Test with a large string with newlines and WNID
    s = "\n".join(["line"] * 500) + "\nn23456789\n"
    codeflash_output = parse_wnid(s) # 7.07μs -> 6.23μs (13.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 spdl.source.imagenet import parse_wnid
import pytest

def test_parse_wnid():
    with pytest.raises(ValueError, match='The\\ given\\ string\\ does\\ not\\ contain\\ WNID:\\ '):
        parse_wnid('')
🔎 Concolic Coverage Tests and Runtime
Test File::Test Function Original ⏱️ Optimized ⏱️ Speedup
codeflash_concolic_xpyvdxks/tmppai3f95x/test_concolic_coverage.py::test_parse_wnid 1.86μs 1.37μs 35.9%✅

To edit these changes git checkout codeflash/optimize-parse_wnid-mgqpw6yf and push.

Codeflash

The optimization replaces the inline regex pattern compilation with a pre-compiled regex pattern stored in a module-level constant `_WNID_RE = re.compile(r"n\d{8}")`. 

**Key optimization**: Instead of recompiling the regex pattern `r"n\d{8}"` on every function call via `re.search()`, the pattern is compiled once at module import time and reused for all subsequent calls.

**Why this is faster**: Regex compilation is computationally expensive, involving pattern parsing, finite state machine construction, and optimization. The line profiler shows the regex search line dropped from 518,553ns to 156,941ns (70% reduction), explaining most of the 45% overall speedup.

**Performance characteristics**: The optimization provides consistent speedup across all test cases (28-76% faster), with particularly strong gains for:
- Simple exact matches (56-70% faster)
- Strings with early matches (65-76% faster) 
- Large strings where the WNID appears early (58-64% faster)

The speedup is less pronounced for cases requiring extensive string scanning (like large strings with WNID at the end or many invalid patterns), but still meaningful at 4-19% improvement. This optimization is especially beneficial for workloads with frequent WNID parsing calls.
@codeflash-ai
codeflash-ai Bot requested a review from mashraf-222 October 14, 2025 15:29
@codeflash-ai codeflash-ai Bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label Oct 14, 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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants