Skip to content

⚡️ Speed up function available_models by 104% - #4

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

⚡️ Speed up function available_models by 104%#4
codeflash-ai[bot] wants to merge 1 commit into
mainfrom
codeflash/optimize-available_models-mayscm19

Conversation

@codeflash-ai

@codeflash-ai codeflash-ai Bot commented May 22, 2025

Copy link
Copy Markdown

📄 104% (1.04x) speedup for available_models in whisper/__init__.py

⏱️ Runtime : 13.3 microseconds 6.53 microseconds (best of 993 runs)

📝 Explanation and details

Optimization rationale:

  • Creating a list from _MODELS.keys() is an O(N) operation and was repeated on every function call.
  • By caching the result at module load in _MODEL_NAMES and returning a copy in each call, we significantly reduce runtime for repeated calls, while still preserving the immutability guarantee for the API user.
  • All comments are preserved; only a new explanatory comment is added for the new variable.
  • The return value remains exactly the same (a fresh list same as before).

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 27 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests Details
from typing import List

# imports
import pytest  # used for our unit tests
from whisper.__init__ import available_models

# function to test
_MODELS = {
    "tiny.en": "https://openaipublic.azureedge.net/main/whisper/models/d3dd57d32accea0b295c96e26691aa14d8822fac7d9d27d5dc00b4ca2826dd03/tiny.en.pt",
    "tiny": "https://openaipublic.azureedge.net/main/whisper/models/65147644a518d12f04e32d6f3b26facc3f8dd46e5390956a9424a650c0ce22b9/tiny.pt",
    "base.en": "https://openaipublic.azureedge.net/main/whisper/models/25a8566e1d0c1e2231d1c762132cd20e0f96a85d16145c3a00adf5d1ac670ead/base.en.pt",
    "base": "https://openaipublic.azureedge.net/main/whisper/models/ed3a0b6b1c0edf879ad9b11b1af5a0e6ab5db9205f891f668f8b0e6c6326e34e/base.pt",
    "small.en": "https://openaipublic.azureedge.net/main/whisper/models/f953ad0fd29cacd07d5a9eda5624af0f6bcf2258be67c92b79389873d91e0872/small.en.pt",
    "small": "https://openaipublic.azureedge.net/main/whisper/models/9ecf779972d90ba49c06d968637d720dd632c55bbf19d441fb42bf17a411e794/small.pt",
    "medium.en": "https://openaipublic.azureedge.net/main/whisper/models/d7440d1dc186f76616474e0ff0b3b6b879abc9d1a4926b7adfa41db2d497ab4f/medium.en.pt",
    "medium": "https://openaipublic.azureedge.net/main/whisper/models/345ae4da62f9b3d59415adc60127b97c714f32e89e936602e85993674d08dcb1/medium.pt",
    "large-v1": "https://openaipublic.azureedge.net/main/whisper/models/e4b87e7e0bf463eb8e6956e646f1e277e901512310def2c24bf0e11bd3c28e9a/large-v1.pt",
    "large-v2": "https://openaipublic.azureedge.net/main/whisper/models/81f7c96c852ee8fc832187b0132e569d6c3065a3252ed18e56effd0b6a73e524/large-v2.pt",
    "large-v3": "https://openaipublic.azureedge.net/main/whisper/models/e5b1a55b89c1367dacf97e3e19bfd829a01529dbfdeefa8caeb59b3f1b81dadb/large-v3.pt",
    "large": "https://openaipublic.azureedge.net/main/whisper/models/e5b1a55b89c1367dacf97e3e19bfd829a01529dbfdeefa8caeb59b3f1b81dadb/large-v3.pt",
    "large-v3-turbo": "https://openaipublic.azureedge.net/main/whisper/models/aff26ae408abcba5fbf8813c21e62b0941638c5f6eebfb145be0c9839262a19a/large-v3-turbo.pt",
    "turbo": "https://openaipublic.azureedge.net/main/whisper/models/aff26ae408abcba5fbf8813c21e62b0941638c5f6eebfb145be0c9839262a19a/large-v3-turbo.pt",
}
from whisper.__init__ import available_models

# unit tests

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

def test_available_models_returns_list():
    # Should always return a list
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_contains_expected_models():
    # Should contain all keys from _MODELS
    codeflash_output = available_models(); result = codeflash_output
    for model in _MODELS.keys():
        pass

def test_available_models_length_matches_models():
    # Should have same length as _MODELS
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_no_duplicates():
    # Should not have duplicate model names
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_order_matches_keys():
    # Should preserve the order of keys in _MODELS (Python 3.7+ dicts are ordered)
    codeflash_output = available_models(); result = codeflash_output
    expected = list(_MODELS.keys())

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

def test_available_models_with_empty_models(monkeypatch):
    # Should return an empty list if _MODELS is empty
    monkeypatch.setitem(globals(), "_MODELS", {})
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_with_one_model(monkeypatch):
    # Should return a single-element list if _MODELS has one entry
    monkeypatch.setitem(globals(), "_MODELS", {"foo": "bar"})
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_with_unusual_model_names(monkeypatch):
    # Should handle keys with unusual characters
    models = {
        "": "empty",
        "model with space": "url1",
        "model-with-dash": "url2",
        "model_with_underscore": "url3",
        "model.with.dot": "url4",
        "model/with/slash": "url5",
        "model😀": "url6",
    }
    monkeypatch.setitem(globals(), "_MODELS", models)
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_is_not_affected_by_external_modification():
    # Should not be affected if the returned list is modified externally
    codeflash_output = available_models(); orig = codeflash_output
    codeflash_output = available_models(); mutated = codeflash_output
    mutated.append("new_model")
    mutated.remove(mutated[0])
    # Call again: should get original result
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_with_large_model_name(monkeypatch):
    # Should handle very long model names
    long_name = "m" * 500
    monkeypatch.setitem(globals(), "_MODELS", {long_name: "url"})
    codeflash_output = available_models(); result = codeflash_output

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

def test_available_models_with_many_models(monkeypatch):
    # Should handle a large number of model names (e.g., 1000)
    n = 1000
    models = {f"model_{i}": f"url_{i}" for i in range(n)}
    monkeypatch.setitem(globals(), "_MODELS", models)
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_performance_large(monkeypatch):
    # Should not take too long for large _MODELS
    import time
    n = 1000
    models = {f"m{i}": f"url{i}" for i in range(n)}
    monkeypatch.setitem(globals(), "_MODELS", models)
    start = time.time()
    codeflash_output = available_models(); result = codeflash_output
    elapsed = time.time() - start

def test_available_models_with_duplicate_urls(monkeypatch):
    # Should allow duplicate URLs but unique model names
    models = {f"m{i}": "url" for i in range(100)}
    monkeypatch.setitem(globals(), "_MODELS", models)
    codeflash_output = available_models(); result = codeflash_output
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

from typing import List

# imports
import pytest  # used for our unit tests
from whisper.__init__ import available_models

# function to test
_MODELS = {
    "tiny.en": "https://openaipublic.azureedge.net/main/whisper/models/d3dd57d32accea0b295c96e26691aa14d8822fac7d9d27d5dc00b4ca2826dd03/tiny.en.pt",
    "tiny": "https://openaipublic.azureedge.net/main/whisper/models/65147644a518d12f04e32d6f3b26facc3f8dd46e5390956a9424a650c0ce22b9/tiny.pt",
    "base.en": "https://openaipublic.azureedge.net/main/whisper/models/25a8566e1d0c1e2231d1c762132cd20e0f96a85d16145c3a00adf5d1ac670ead/base.en.pt",
    "base": "https://openaipublic.azureedge.net/main/whisper/models/ed3a0b6b1c0edf879ad9b11b1af5a0e6ab5db9205f891f668f8b0e6c6326e34e/base.pt",
    "small.en": "https://openaipublic.azureedge.net/main/whisper/models/f953ad0fd29cacd07d5a9eda5624af0f6bcf2258be67c92b79389873d91e0872/small.en.pt",
    "small": "https://openaipublic.azureedge.net/main/whisper/models/9ecf779972d90ba49c06d968637d720dd632c55bbf19d441fb42bf17a411e794/small.pt",
    "medium.en": "https://openaipublic.azureedge.net/main/whisper/models/d7440d1dc186f76616474e0ff0b3b6b879abc9d1a4926b7adfa41db2d497ab4f/medium.en.pt",
    "medium": "https://openaipublic.azureedge.net/main/whisper/models/345ae4da62f9b3d59415adc60127b97c714f32e89e936602e85993674d08dcb1/medium.pt",
    "large-v1": "https://openaipublic.azureedge.net/main/whisper/models/e4b87e7e0bf463eb8e6956e646f1e277e901512310def2c24bf0e11bd3c28e9a/large-v1.pt",
    "large-v2": "https://openaipublic.azureedge.net/main/whisper/models/81f7c96c852ee8fc832187b0132e569d6c3065a3252ed18e56effd0b6a73e524/large-v2.pt",
    "large-v3": "https://openaipublic.azureedge.net/main/whisper/models/e5b1a55b89c1367dacf97e3e19bfd829a01529dbfdeefa8caeb59b3f1b81dadb/large-v3.pt",
    "large": "https://openaipublic.azureedge.net/main/whisper/models/e5b1a55b89c1367dacf97e3e19bfd829a01529dbfdeefa8caeb59b3f1b81dadb/large-v3.pt",
    "large-v3-turbo": "https://openaipublic.azureedge.net/main/whisper/models/aff26ae408abcba5fbf8813c21e62b0941638c5f6eebfb145be0c9839262a19a/large-v3-turbo.pt",
    "turbo": "https://openaipublic.azureedge.net/main/whisper/models/aff26ae408abcba5fbf8813c21e62b0941638c5f6eebfb145be0c9839262a19a/large-v3-turbo.pt",
}
from whisper.__init__ import available_models

# ------------------- UNIT TESTS -------------------

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

def test_available_models_basic_content():
    # The function should return all and only the keys of _MODELS
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_no_duplicates():
    # There should be no duplicate model names
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_nonempty():
    # The function should return a non-empty list when _MODELS is non-empty
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_expected_subset():
    # Check that some expected model names are present
    expected = {"tiny", "base", "small", "medium", "large", "turbo"}
    result = set(available_models())

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

def test_available_models_empty(monkeypatch):
    # If _MODELS is empty, should return an empty list
    monkeypatch.setitem(globals(), "_MODELS", {})
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_special_characters(monkeypatch):
    # Model names with special characters should be returned as-is
    special_models = {
        "model-1": "url1",
        "model_2": "url2",
        "model 3": "url3",
        "模型四": "url4",  # Unicode
        "": "url5",       # Empty string as key
        "model@6!": "url6"
    }
    monkeypatch.setitem(globals(), "_MODELS", special_models)
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_large_keys(monkeypatch):
    # Model names with very long strings should be handled
    long_key = "m" * 500
    monkeypatch.setitem(globals(), "_MODELS", {long_key: "url"})
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_non_string_keys(monkeypatch):
    # If _MODELS has non-string keys, should still return them as-is (Python dict allows this)
    # But our contract says "List[str]", so let's see if it returns them as-is (should fail type check but not runtime)
    mixed_keys = {123: "url1", None: "url2", "valid": "url3"}
    monkeypatch.setitem(globals(), "_MODELS", mixed_keys)
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_keys_order(monkeypatch):
    # The order of keys returned should match the insertion order of the dict (Python 3.7+)
    ordered_keys = ["a", "b", "c", "d"]
    monkeypatch.setitem(globals(), "_MODELS", {k: f"url_{k}" for k in ordered_keys})
    codeflash_output = available_models(); result = codeflash_output

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

def test_available_models_large_scale(monkeypatch):
    # Test with 1000 entries to check scalability and performance
    n = 1000
    keys = [f"model_{i}" for i in range(n)]
    large_models = {k: f"url_{i}" for i, k in enumerate(keys)}
    monkeypatch.setitem(globals(), "_MODELS", large_models)
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_large_scale_special_keys(monkeypatch):
    # Test with 1000 entries, some with special characters and unicode
    n = 1000
    keys = [f"model_{i}" for i in range(n-3)] + ["模型A", "model space", "model-!@#"]
    large_models = {k: f"url_{i}" for i, k in enumerate(keys)}
    monkeypatch.setitem(globals(), "_MODELS", large_models)
    codeflash_output = available_models(); result = codeflash_output

def test_available_models_performance(monkeypatch):
    # This test is not a strict performance test but ensures function runs in reasonable time for 1000 keys
    import time
    n = 1000
    keys = [f"model_{i}" for i in range(n)]
    large_models = {k: f"url_{i}" for i, k in enumerate(keys)}
    monkeypatch.setitem(globals(), "_MODELS", large_models)
    start = time.time()
    codeflash_output = available_models(); result = codeflash_output
    end = time.time()
# 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-available_models-mayscm19 and push.

Codeflash

**Optimization rationale:**
- Creating a list from `_MODELS.keys()` is an O(N) operation and was repeated on every function call.
- By caching the result at module load in `_MODEL_NAMES` and returning a copy in each call, we significantly reduce runtime for repeated calls, while still preserving the immutability guarantee for the API user.
- All comments are preserved; only a new explanatory comment is added for the new variable.  
- The return value remains exactly the same (a fresh `list` same as before).
@codeflash-ai codeflash-ai Bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label May 22, 2025
@codeflash-ai
codeflash-ai Bot requested a review from HeshamHM28 May 22, 2025 03:01
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