Skip to content

⚡️ Speed up function get_mappings by 1,365% - #8

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

⚡️ Speed up function get_mappings by 1,365%#8
codeflash-ai[bot] wants to merge 1 commit into
mainfrom
codeflash/optimize-get_mappings-mgqq2tdn

Conversation

@codeflash-ai

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

Copy link
Copy Markdown

📄 1,365% (13.65x) speedup for get_mappings in src/spdl/source/imagenet.py

⏱️ Runtime : 2.51 milliseconds 171 microseconds (best of 450 runs)

📝 Explanation and details

The optimization moves the large 1000-entry ImageNet dictionary from being recreated on every function call to being defined once as a module-level constant _IMAGENET_WORDNETID_TO_CLASSIDX. The get_mappings() function now simply returns dict(_IMAGENET_WORDNETID_TO_CLASSIDX) instead of constructing the entire dictionary from scratch each time.

Key performance improvements:

  • Eliminates dictionary construction overhead: The original code created 1000 key-value pairs on every call, while the optimized version only copies an existing dictionary
  • Reduces memory allocation: Instead of allocating memory for 1000 string/int pairs repeatedly, it performs one efficient dictionary copy operation
  • Maintains behavioral contract: Still returns a fresh dictionary that callers can safely mutate without affecting future calls

Why this optimization is effective:
The line profiler shows the original code spent 98.3% of its time (555ms out of 565ms total) on the dictionary literal construction. Dictionary copying in Python is highly optimized at the C level, making it orders of magnitude faster than reconstructing the same static data repeatedly.

Test case performance pattern:
All test cases show consistent 13-14x speedups (1200-1400% faster), indicating this optimization benefits any usage pattern - whether calling the function once or thousands of times. The speedup is particularly valuable for ML/computer vision workflows where ImageNet mappings might be accessed frequently during data preprocessing or model inference.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 49 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 1 Passed
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
import pytest
from spdl.source.imagenet import get_mappings

# unit tests

# ----------------- BASIC TEST CASES -----------------

def test_mapping_type_and_length():
    # Test that the returned object is a dict and has 1000 entries
    codeflash_output = get_mappings(); mapping = codeflash_output # 47.8μs -> 3.49μs (1268% faster)

def test_known_ids_and_indices():
    # Test a few known mappings from the docstring and early/late/edge entries
    codeflash_output = get_mappings(); mapping = codeflash_output # 47.5μs -> 3.47μs (1269% faster)

def test_unique_indices_and_keys():
    # Test that all indices and keys are unique
    codeflash_output = get_mappings(); mapping = codeflash_output # 47.9μs -> 3.44μs (1292% faster)
    indices = list(mapping.values())
    keys = list(mapping.keys())

def test_indices_are_consecutive():
    # Test that all indices are consecutive from 0 to 999
    codeflash_output = get_mappings(); mapping = codeflash_output # 48.4μs -> 3.37μs (1338% faster)
    indices = sorted(mapping.values())

def test_keys_format():
    # Test that all keys are strings of the correct format (start with 'n' and have 8 digits)
    codeflash_output = get_mappings(); mapping = codeflash_output # 49.5μs -> 3.44μs (1340% faster)
    for k in mapping.keys():
        pass

def test_indices_are_ints():
    # Test that all values are integers
    codeflash_output = get_mappings(); mapping = codeflash_output # 49.1μs -> 3.44μs (1327% faster)
    for v in mapping.values():
        pass

# ----------------- EDGE TEST CASES -----------------

def test_nonexistent_key_raises_keyerror():
    # Test that accessing a non-existent key raises KeyError
    codeflash_output = get_mappings(); mapping = codeflash_output # 51.4μs -> 3.47μs (1384% faster)
    with pytest.raises(KeyError):
        _ = mapping["n00000000"]

def test_min_and_max_indices():
    # Test that the minimum and maximum indices are 0 and 999
    codeflash_output = get_mappings(); mapping = codeflash_output # 51.9μs -> 3.46μs (1397% faster)
    indices = mapping.values()

def test_no_extra_keys():
    # Test that there are no keys outside the expected pattern
    codeflash_output = get_mappings(); mapping = codeflash_output # 52.0μs -> 3.43μs (1417% faster)
    for k in mapping.keys():
        pass

def test_no_duplicate_indices():
    # Test that each index occurs exactly once
    codeflash_output = get_mappings(); mapping = codeflash_output # 50.7μs -> 3.42μs (1380% faster)
    indices = list(mapping.values())

def test_sorted_wordnet_ids():
    # Test that the indices correspond to the position in the sorted list of keys
    codeflash_output = get_mappings(); mapping = codeflash_output # 51.9μs -> 3.44μs (1409% faster)
    sorted_keys = sorted(mapping.keys())
    for idx, k in enumerate(sorted_keys):
        pass

def test_keys_are_not_empty():
    # Test that no key is an empty string
    codeflash_output = get_mappings(); mapping = codeflash_output # 50.9μs -> 3.50μs (1355% faster)
    for k in mapping.keys():
        pass

# ----------------- LARGE SCALE TEST CASES -----------------

def test_all_indices_present():
    # Test that all indices from 0 to 999 are present as values
    codeflash_output = get_mappings(); mapping = codeflash_output # 52.2μs -> 3.38μs (1444% faster)
    indices = set(mapping.values())

def test_performance_large_scale(monkeypatch):
    # Test that get_mappings runs efficiently and returns the correct size for large scale
    import time
    start_time = time.time()
    codeflash_output = get_mappings(); mapping = codeflash_output # 52.4μs -> 3.61μs (1349% faster)
    elapsed = time.time() - start_time

def test_mapping_is_immutable(monkeypatch):
    # Test that get_mappings returns a new dict each time (not a shared mutable object)
    codeflash_output = get_mappings(); m1 = codeflash_output # 52.3μs -> 3.50μs (1394% faster)
    codeflash_output = get_mappings(); m2 = codeflash_output # 46.4μs -> 3.35μs (1283% faster)
    m1["n01440764"] = -1

def test_all_keys_are_strings():
    # Test that all keys are strings (repeat for large scale)
    codeflash_output = get_mappings(); mapping = codeflash_output # 49.2μs -> 3.36μs (1364% faster)

def test_all_values_are_ints():
    # Test that all values are ints (repeat for large scale)
    codeflash_output = get_mappings(); mapping = codeflash_output # 48.4μs -> 3.35μs (1343% faster)

def test_no_key_is_none():
    # Test that no key is None
    codeflash_output = get_mappings(); mapping = codeflash_output # 48.4μs -> 3.42μs (1315% faster)

def test_no_value_is_none():
    # Test that no value is None
    codeflash_output = get_mappings(); mapping = codeflash_output # 50.6μs -> 3.39μs (1391% faster)

def test_keys_are_ascii():
    # Test that all keys are ASCII
    codeflash_output = get_mappings(); mapping = codeflash_output # 50.6μs -> 3.41μs (1384% faster)
    for k in mapping.keys():
        try:
            k.encode('ascii')
        except UnicodeEncodeError:
            raise AssertionError(f"Key {k} is not ASCII")

def test_values_are_within_range():
    # Test that all values are within the expected range (0-999)
    codeflash_output = get_mappings(); mapping = codeflash_output # 49.8μs -> 3.45μs (1345% faster)
    for v in mapping.values():
        pass
# 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 spdl.source.imagenet import get_mappings

# unit tests

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

def test_mapping_contains_known_keys():
    # Test that a few known keys exist and map to the correct values
    codeflash_output = get_mappings(); mapping = codeflash_output # 52.5μs -> 3.50μs (1399% faster)

def test_mapping_length_is_1000():
    # Test that there are exactly 1000 mappings
    codeflash_output = get_mappings(); mapping = codeflash_output # 52.4μs -> 3.38μs (1451% faster)

def test_mapping_keys_are_strings_and_values_are_ints():
    # Test that all keys are strings and all values are ints
    codeflash_output = get_mappings(); mapping = codeflash_output # 53.3μs -> 3.40μs (1465% faster)
    for k, v in mapping.items():
        pass

def test_mapping_is_consistent_on_multiple_calls():
    # Test that calling get_mappings() multiple times returns the same mapping
    codeflash_output = get_mappings(); mapping1 = codeflash_output # 52.5μs -> 3.41μs (1437% faster)
    codeflash_output = get_mappings(); mapping2 = codeflash_output # 47.1μs -> 3.20μs (1371% faster)

def test_mapping_is_not_empty():
    # Test that the mapping is not empty
    codeflash_output = get_mappings(); mapping = codeflash_output # 48.7μs -> 3.37μs (1346% faster)

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

def test_mapping_class_indices_are_unique_and_in_range():
    # Test that all class indices are unique and in the range 0-999
    codeflash_output = get_mappings(); mapping = codeflash_output # 48.5μs -> 3.38μs (1333% faster)
    indices = list(mapping.values())

def test_invalid_key_raises_keyerror():
    # Test that looking up a non-existent key raises KeyError
    codeflash_output = get_mappings(); mapping = codeflash_output # 48.2μs -> 3.48μs (1286% faster)
    with pytest.raises(KeyError):
        _ = mapping["not_a_wnid"]

def test_keys_are_wnid_format():
    # Test that all keys are in the expected WordNet ID format: n\d{8}
    import re
    codeflash_output = get_mappings(); mapping = codeflash_output # 50.5μs -> 3.44μs (1371% faster)
    pattern = re.compile(r"^n\d{8}$")
    for k in mapping.keys():
        pass

def test_mapping_is_not_mutable():
    # Test that modifying the returned mapping does not affect future calls
    codeflash_output = get_mappings(); mapping1 = codeflash_output # 50.2μs -> 3.38μs (1387% faster)
    mapping1["n01440764"] = -1
    codeflash_output = get_mappings(); mapping2 = codeflash_output # 44.5μs -> 3.43μs (1196% faster)

def test_mapping_is_sorted_by_index():
    # Test that if we sort by value, the keys are in increasing WNID order
    codeflash_output = get_mappings(); mapping = codeflash_output # 47.3μs -> 3.34μs (1315% faster)
    # Get list of (wnid, idx) sorted by idx
    sorted_by_index = sorted(mapping.items(), key=lambda x: x[1])
    wnids_sorted = [wnid for wnid, idx in sorted_by_index]
    # The mapping claims indices correspond to sorted WNIDs
    wnids_sorted_expected = sorted(mapping.keys())

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

def test_all_indices_map_to_unique_wnid():
    # Test that every index 0-999 maps to exactly one WNID
    codeflash_output = get_mappings(); mapping = codeflash_output # 47.1μs -> 3.55μs (1224% faster)
    reverse = {}
    for wnid, idx in mapping.items():
        reverse[idx] = wnid

def test_batch_lookup_performance_and_correctness():
    # Test that batch lookup of all keys returns correct indices
    codeflash_output = get_mappings(); mapping = codeflash_output # 49.6μs -> 3.51μs (1312% faster)
    # Look up all keys and verify their indices are in the correct range
    for wnid in list(mapping.keys())[:1000]:  # all keys
        idx = mapping[wnid]

def test_no_duplicate_wnids():
    # Test that there are no duplicate WNIDs (keys)
    codeflash_output = get_mappings(); mapping = codeflash_output # 50.9μs -> 3.42μs (1388% faster)
    all_keys = list(mapping.keys())

def test_no_duplicate_indices():
    # Test that there are no duplicate indices (values)
    codeflash_output = get_mappings(); mapping = codeflash_output # 51.6μs -> 3.43μs (1405% faster)
    all_indices = list(mapping.values())

def test_mapping_can_be_used_for_reverse_lookup():
    # Test that we can reconstruct WNID from index
    codeflash_output = get_mappings(); mapping = codeflash_output # 51.1μs -> 3.44μs (1387% faster)
    reverse = {idx: wnid for wnid, idx in mapping.items()}
    for wnid, idx in mapping.items():
        pass

def test_all_wnids_are_lexicographically_sorted_by_index():
    # Test that the mapping's indices correspond to lexicographically sorted WNIDs
    codeflash_output = get_mappings(); mapping = codeflash_output # 51.6μs -> 3.46μs (1392% faster)
    wnids_sorted = sorted(mapping.keys())
    for idx, wnid in enumerate(wnids_sorted):
        pass

# ----------- Additional Edge and Robustness Cases -----------

def test_mapping_is_a_dict():
    # Test that the returned object is a dict
    codeflash_output = get_mappings(); mapping = codeflash_output # 52.3μs -> 3.48μs (1402% faster)

def test_mapping_is_not_none():
    # Test that the returned mapping is not None
    codeflash_output = get_mappings(); mapping = codeflash_output # 52.1μs -> 3.43μs (1420% faster)

def test_mapping_has_no_none_keys_or_values():
    # Test that there are no None keys or values
    codeflash_output = get_mappings(); mapping = codeflash_output # 52.0μs -> 3.42μs (1421% faster)
    for k, v in mapping.items():
        pass

def test_mapping_has_no_negative_indices():
    # Test that there are no negative indices
    codeflash_output = get_mappings(); mapping = codeflash_output # 51.1μs -> 3.42μs (1394% faster)
    for idx in mapping.values():
        pass

def test_mapping_keys_are_ascii():
    # Test that all keys are ASCII
    codeflash_output = get_mappings(); mapping = codeflash_output # 51.3μs -> 3.40μs (1407% faster)
    for k in mapping.keys():
        try:
            k.encode("ascii")
        except UnicodeEncodeError:
            pytest.fail(f"Key {k} is not ASCII")

def test_mapping_values_are_integers_and_not_floats():
    # Test that all values are strictly int, not float
    codeflash_output = get_mappings(); mapping = codeflash_output # 51.5μs -> 3.43μs (1401% faster)
    for v in mapping.values():
        pass

def test_mapping_repr_is_not_empty():
    # Test that repr(mapping) is non-empty and contains at least one key
    codeflash_output = get_mappings(); mapping = codeflash_output # 52.0μs -> 3.36μs (1445% faster)
    s = repr(mapping)

def test_mapping_is_copy_on_return():
    # Test that the returned dict is not the same object on multiple calls
    codeflash_output = get_mappings(); mapping1 = codeflash_output # 52.3μs -> 3.45μs (1416% faster)
    codeflash_output = get_mappings(); mapping2 = codeflash_output # 46.5μs -> 3.28μs (1318% 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 get_mappings

def test_get_mappings():
    get_mappings()
🔎 Concolic Coverage Tests and Runtime
Test File::Test Function Original ⏱️ Optimized ⏱️ Speedup
codeflash_concolic_xpyvdxks/tmpxl_hvfrs/test_concolic_coverage.py::test_get_mappings 53.3μs 3.56μs 1399%✅

To edit these changes git checkout codeflash/optimize-get_mappings-mgqq2tdn and push.

Codeflash

The optimization moves the large 1000-entry ImageNet dictionary from being recreated on every function call to being defined once as a module-level constant `_IMAGENET_WORDNETID_TO_CLASSIDX`. The `get_mappings()` function now simply returns `dict(_IMAGENET_WORDNETID_TO_CLASSIDX)` instead of constructing the entire dictionary from scratch each time.

**Key performance improvements:**
- **Eliminates dictionary construction overhead**: The original code created 1000 key-value pairs on every call, while the optimized version only copies an existing dictionary
- **Reduces memory allocation**: Instead of allocating memory for 1000 string/int pairs repeatedly, it performs one efficient dictionary copy operation
- **Maintains behavioral contract**: Still returns a fresh dictionary that callers can safely mutate without affecting future calls

**Why this optimization is effective:**
The line profiler shows the original code spent 98.3% of its time (555ms out of 565ms total) on the dictionary literal construction. Dictionary copying in Python is highly optimized at the C level, making it orders of magnitude faster than reconstructing the same static data repeatedly.

**Test case performance pattern:**
All test cases show consistent 13-14x speedups (1200-1400% faster), indicating this optimization benefits any usage pattern - whether calling the function once or thousands of times. The speedup is particularly valuable for ML/computer vision workflows where ImageNet mappings might be accessed frequently during data preprocessing or model inference.
@codeflash-ai
codeflash-ai Bot requested a review from mashraf-222 October 14, 2025 15:34
@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