Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Nov 7, 2025

📄 9% (0.09x) speedup for VertexGeminiConfig.get_tool_value in litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py

⏱️ Runtime : 139 microseconds 127 microseconds (best of 162 runs)

📝 Explanation and details

The optimized code achieves a 9% speedup through two key optimizations:

1. __init__ Method Optimization:
The original code used locals().copy() and iterated through all local variables, which creates unnecessary overhead. The optimized version directly checks each parameter individually with explicit if statements, avoiding dictionary creation and iteration. This is more efficient since most parameters are typically None during initialization.

2. get_tool_value Method Optimization:

  • Eliminated redundant dictionary lookups: The original code called tool.get() multiple times for the same key. The optimized version stores the result in a variable and reuses it, reducing dictionary access overhead.
  • Improved string conversion logic: Instead of using a list comprehension with conditional expressions inside "".join(), the optimized version uses a simple loop with explicit character appending, which is more efficient for string building operations.

Performance Benefits by Test Case:

  • Short strings (empty, single char): Show the largest improvements (26-55% faster) due to reduced overhead
  • Complex camelCase conversions: Moderate improvements (3-15% faster) from more efficient string processing
  • Large dictionaries: Consistent 5-15% improvements from reduced dictionary lookups
  • Error cases: 5-20% faster due to streamlined execution paths

The optimizations are particularly effective for frequently called utility functions like get_tool_value, which appears to be used extensively in tool configuration scenarios. The improvements scale well with both simple and complex inputs while maintaining identical functionality.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 106 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
import pytest
from litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import \
    VertexGeminiConfig

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

def test_get_tool_value_camel_case_found():
    # Test that camelCase key returns correct value
    config = VertexGeminiConfig()
    tool = {"codeExecution": {"enabled": True}}
    codeflash_output = config.get_tool_value(tool, "codeExecution"); result = codeflash_output # 2.64μs -> 2.37μs (11.3% faster)

def test_get_tool_value_underscore_case_found():
    # Test that underscore_case key returns correct value
    config = VertexGeminiConfig()
    tool = {"code_execution": {"enabled": False}}
    codeflash_output = config.get_tool_value(tool, "codeExecution"); result = codeflash_output # 2.71μs -> 2.59μs (4.67% faster)

def test_get_tool_value_both_keys_present():
    # If both camelCase and underscore_case are present, camelCase should take precedence
    config = VertexGeminiConfig()
    tool = {
        "codeExecution": {"enabled": True},
        "code_execution": {"enabled": False}
    }
    codeflash_output = config.get_tool_value(tool, "codeExecution"); result = codeflash_output # 2.47μs -> 2.29μs (7.96% faster)

def test_get_tool_value_neither_key_present():
    # If neither key is present, should return None
    config = VertexGeminiConfig()
    tool = {"somethingElse": 123}
    codeflash_output = config.get_tool_value(tool, "codeExecution"); result = codeflash_output # 2.56μs -> 2.44μs (4.63% faster)

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

def test_get_tool_value_empty_dict():
    # Empty dict should always return None
    config = VertexGeminiConfig()
    tool = {}
    codeflash_output = config.get_tool_value(tool, "codeExecution"); result = codeflash_output # 2.57μs -> 2.51μs (2.59% faster)

def test_get_tool_value_empty_tool_name():
    # Empty tool_name: should look for "" and "_" (which is not likely to be present)
    config = VertexGeminiConfig()
    tool = {"": "empty", "_": "underscore"}
    codeflash_output = config.get_tool_value(tool, ""); result = codeflash_output # 1.29μs -> 917ns (41.0% faster)

def test_get_tool_value_tool_name_single_uppercase():
    # Single uppercase letter as tool_name
    config = VertexGeminiConfig()
    tool = {"A": 1, "a": 2}
    codeflash_output = config.get_tool_value(tool, "A"); result = codeflash_output # 1.92μs -> 1.55μs (24.1% faster)

def test_get_tool_value_tool_name_all_uppercase():
    # All uppercase tool_name (should convert to all lowercase with underscores between each)
    config = VertexGeminiConfig()
    tool = {"APIKEY": "val1", "a_p_i_k_e_y": "val2"}
    codeflash_output = config.get_tool_value(tool, "APIKEY"); result = codeflash_output # 2.80μs -> 2.43μs (15.5% faster)

def test_get_tool_value_tool_name_all_lowercase():
    # All lowercase tool_name (underscore_name will be the same)
    config = VertexGeminiConfig()
    tool = {"apiname": "val1", "apiname": "val2"}
    codeflash_output = config.get_tool_value(tool, "apiname"); result = codeflash_output # 2.03μs -> 1.85μs (9.90% faster)

def test_get_tool_value_none_values():
    # If key exists but value is None, should skip to the next variant
    config = VertexGeminiConfig()
    tool = {"codeExecution": None, "code_execution": {"enabled": 42}}
    codeflash_output = config.get_tool_value(tool, "codeExecution"); result = codeflash_output # 2.84μs -> 2.72μs (4.22% faster)

def test_get_tool_value_key_exists_but_value_is_false():
    # If value is False (not None), should return False, not skip
    config = VertexGeminiConfig()
    tool = {"codeExecution": False}
    codeflash_output = config.get_tool_value(tool, "codeExecution"); result = codeflash_output # 2.56μs -> 2.31μs (10.9% faster)

def test_get_tool_value_key_exists_but_value_is_zero():
    # If value is 0 (not None), should return 0, not skip
    config = VertexGeminiConfig()
    tool = {"codeExecution": 0}
    codeflash_output = config.get_tool_value(tool, "codeExecution"); result = codeflash_output # 2.55μs -> 2.39μs (6.74% faster)

def test_get_tool_value_tool_name_with_multiple_caps():
    # Tool name with multiple uppercase letters (e.g., "myHTTPServer")
    config = VertexGeminiConfig()
    tool = {"myHTTPServer": "camel", "my_h_t_t_p_server": "snake"}
    codeflash_output = config.get_tool_value(tool, "myHTTPServer"); result = codeflash_output # 3.04μs -> 2.94μs (3.54% faster)

def test_get_tool_value_tool_name_with_leading_underscore():
    # Tool name with leading underscore (should not add extra underscores)
    config = VertexGeminiConfig()
    tool = {"_hiddenTool": "camel", "hidden_tool": "snake"}
    codeflash_output = config.get_tool_value(tool, "_hiddenTool"); result = codeflash_output # 2.67μs -> 2.42μs (10.5% faster)

def test_get_tool_value_tool_name_with_trailing_underscore():
    # Tool name with trailing underscore (should not add extra underscores)
    config = VertexGeminiConfig()
    tool = {"trailing_": "snake"}
    codeflash_output = config.get_tool_value(tool, "trailing_"); result = codeflash_output # 2.02μs -> 1.90μs (6.32% faster)

def test_get_tool_value_tool_name_with_numbers():
    # Tool name with numbers in it
    config = VertexGeminiConfig()
    tool = {"tool2Execution": "camel", "tool2_execution": "snake"}
    codeflash_output = config.get_tool_value(tool, "tool2Execution"); result = codeflash_output # 2.63μs -> 2.53μs (3.87% faster)

def test_get_tool_value_tool_name_with_special_chars():
    # Tool name with special characters (should not be altered)
    config = VertexGeminiConfig()
    tool = {"tool$Execution": "camel", "tool$_execution": "snake"}
    codeflash_output = config.get_tool_value(tool, "tool$Execution"); result = codeflash_output # 2.60μs -> 2.39μs (9.09% faster)

def test_get_tool_value_tool_name_with_underscore_only():
    # Tool name is just an underscore
    config = VertexGeminiConfig()
    tool = {"_": "underscore"}
    codeflash_output = config.get_tool_value(tool, "_"); result = codeflash_output # 1.56μs -> 1.23μs (26.3% faster)

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

def test_get_tool_value_large_dict_camel_case():
    # Large dict where only one camelCase key matches
    config = VertexGeminiConfig()
    tool = {f"key{i}": i for i in range(1000)}
    tool["bigToolName"] = {"payload": "found"}
    codeflash_output = config.get_tool_value(tool, "bigToolName"); result = codeflash_output # 2.85μs -> 2.68μs (6.65% faster)

def test_get_tool_value_large_dict_underscore_case():
    # Large dict where only underscore_case key matches
    config = VertexGeminiConfig()
    tool = {f"key_{i}": i for i in range(1000)}
    tool["big_tool_name"] = {"payload": "found"}
    codeflash_output = config.get_tool_value(tool, "bigToolName"); result = codeflash_output # 2.94μs -> 2.83μs (4.03% faster)

def test_get_tool_value_large_dict_neither_key():
    # Large dict with no matching key
    config = VertexGeminiConfig()
    tool = {f"key{i}": i for i in range(1000)}
    codeflash_output = config.get_tool_value(tool, "nonExistentTool"); result = codeflash_output # 2.93μs -> 2.94μs (0.543% slower)

def test_get_tool_value_large_dict_both_keys():
    # Large dict with both variants, camelCase should take precedence
    config = VertexGeminiConfig()
    tool = {f"key{i}": i for i in range(998)}
    tool["bigToolName"] = {"payload": "camel"}
    tool["big_tool_name"] = {"payload": "snake"}
    codeflash_output = config.get_tool_value(tool, "bigToolName"); result = codeflash_output # 2.54μs -> 2.45μs (3.64% faster)

def test_get_tool_value_performance_large():
    # Performance: Ensure function is efficient for large dicts (under 1000 elements)
    import time
    config = VertexGeminiConfig()
    tool = {f"tool_{i}": i for i in range(999)}
    tool["targetTool"] = {"data": 123}
    start = time.time()
    codeflash_output = config.get_tool_value(tool, "targetTool"); result = codeflash_output # 2.50μs -> 2.29μs (9.07% faster)
    end = time.time()

# -------------------------------
# Additional Robustness Tests
# -------------------------------

def test_get_tool_value_non_dict_value():
    # If the value is not a dict, should still return it
    config = VertexGeminiConfig()
    tool = {"codeExecution": 42}
    codeflash_output = config.get_tool_value(tool, "codeExecution"); result = codeflash_output # 2.72μs -> 2.42μs (12.3% faster)

def test_get_tool_value_tool_is_none():
    # If tool is None, should raise AttributeError
    config = VertexGeminiConfig()
    with pytest.raises(AttributeError):
        config.get_tool_value(None, "codeExecution") # 3.29μs -> 3.11μs (5.73% faster)

def test_get_tool_value_tool_is_not_dict():
    # If tool is not a dict, should raise AttributeError
    config = VertexGeminiConfig()
    with pytest.raises(AttributeError):
        config.get_tool_value(123, "codeExecution") # 3.48μs -> 3.21μs (8.15% faster)

def test_get_tool_value_tool_name_is_none():
    # If tool_name is None, should raise TypeError in key conversion
    config = VertexGeminiConfig()
    tool = {"None": "val"}
    with pytest.raises(TypeError):
        config.get_tool_value(tool, None) # 1.27μs -> 1.06μs (19.7% faster)

def test_get_tool_value_tool_name_is_int():
    # If tool_name is int, should raise AttributeError in key conversion
    config = VertexGeminiConfig()
    tool = {1: "val"}
    with pytest.raises(AttributeError):
        config.get_tool_value(tool, 1)
# 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 litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini import \
    VertexGeminiConfig

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

@pytest.fixture
def config():
    # Fixture to provide a VertexGeminiConfig instance
    return VertexGeminiConfig()

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

def test_camel_case_key_found(config):
    # Basic: tool contains camelCase key
    tool = {"codeExecution": {"result": 42}}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 3.52μs -> 3.23μs (8.92% faster)

def test_underscore_case_key_found(config):
    # Basic: tool contains underscore_case key
    tool = {"code_execution": {"result": 99}}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 3.15μs -> 2.84μs (11.0% faster)

def test_both_keys_present_prefers_camel_case(config):
    # Basic: both camelCase and underscore_case present, should prefer camelCase
    tool = {
        "codeExecution": {"result": 1},
        "code_execution": {"result": 2}
    }
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.80μs -> 2.45μs (14.4% faster)

def test_key_not_found_returns_none(config):
    # Basic: neither key is present
    tool = {"somethingElse": {"foo": "bar"}}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.79μs -> 2.56μs (9.23% faster)

def test_empty_dict_returns_none(config):
    # Basic: empty dict
    tool = {}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.83μs -> 2.63μs (7.37% faster)

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

def test_tool_value_is_none(config):
    # Edge: tool contains key but value is None
    tool = {"codeExecution": None}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.84μs -> 2.63μs (8.14% faster)

def test_tool_value_is_falsey_but_not_none(config):
    # Edge: tool contains key with falsey value (e.g. empty dict)
    tool = {"codeExecution": {}}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.68μs -> 2.40μs (11.7% faster)

def test_tool_value_is_zero(config):
    # Edge: tool contains key with value 0 (should return 0)
    tool = {"codeExecution": 0}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.50μs -> 2.31μs (7.99% faster)

def test_tool_value_is_empty_list(config):
    # Edge: tool contains key with empty list
    tool = {"codeExecution": []}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.54μs -> 2.39μs (6.49% faster)

def test_tool_name_is_empty_string(config):
    # Edge: tool_name is empty string
    tool = {"": {"empty": True}}
    codeflash_output = config.get_tool_value(tool, "") # 1.39μs -> 894ns (55.4% faster)

def test_tool_name_is_all_uppercase(config):
    # Edge: tool_name is all uppercase (should not match)
    tool = {"codeExecution": {"result": 1}, "CODEEXECUTION": {"result": 2}}
    codeflash_output = config.get_tool_value(tool, "CODEEXECUTION") # 3.70μs -> 3.34μs (10.8% faster)

def test_tool_with_similar_keys(config):
    # Edge: tool dict has similar but not matching keys
    tool = {"codeExecutions": {"foo": "bar"}, "code_execution": {"result": 5}}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.88μs -> 2.71μs (6.19% faster)

def test_tool_name_with_multiple_uppercase_letters(config):
    # Edge: tool_name with multiple uppercase letters
    tool = {"myHTTPParser": {"ok": True}, "my_http_parser": {"ok": False}}
    codeflash_output = config.get_tool_value(tool, "myHTTPParser") # 3.16μs -> 2.98μs (6.35% faster)

def test_tool_name_with_leading_underscore(config):
    # Edge: tool_name with leading underscore
    tool = {"_codeExecution": {"result": 3}, "code_execution": {"result": 4}}
    codeflash_output = config.get_tool_value(tool, "_codeExecution") # 2.80μs -> 2.60μs (7.65% faster)

def test_tool_name_with_numbers(config):
    # Edge: tool_name contains numbers
    tool = {"tool2Execution": {"v": 2}, "tool2_execution": {"v": 3}}
    codeflash_output = config.get_tool_value(tool, "tool2Execution") # 2.62μs -> 2.44μs (7.38% faster)

def test_tool_name_with_only_one_letter(config):
    # Edge: tool_name is a single letter
    tool = {"A": {"val": 1}, "a": {"val": 2}}
    codeflash_output = config.get_tool_value(tool, "A") # 1.89μs -> 1.54μs (22.2% faster)

def test_tool_name_with_no_uppercase(config):
    # Edge: tool_name is all lowercase
    tool = {"codeexecution": {"result": 7}}
    codeflash_output = config.get_tool_value(tool, "codeexecution") # 2.24μs -> 2.11μs (6.51% faster)

def test_tool_dict_with_non_string_keys(config):
    # Edge: tool dict has non-string keys
    tool = {123: "number", "codeExecution": {"result": 8}}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.77μs -> 2.47μs (11.8% faster)

def test_tool_dict_is_none(config):
    # Edge: tool is None (should raise AttributeError)
    with pytest.raises(AttributeError):
        config.get_tool_value(None, "codeExecution") # 3.65μs -> 3.26μs (11.7% faster)

def test_tool_dict_is_not_a_dict(config):
    # Edge: tool is not a dict (should raise AttributeError)
    with pytest.raises(AttributeError):
        config.get_tool_value(["not", "a", "dict"], "codeExecution") # 3.66μs -> 3.25μs (12.7% faster)

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

def test_large_tool_dict_camel_case(config):
    # Large Scale: tool dict with 1000 keys, camelCase key present
    tool = {f"key{i}": i for i in range(1000)}
    tool["codeExecution"] = {"result": 1001}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.90μs -> 2.61μs (11.1% faster)

def test_large_tool_dict_underscore_case(config):
    # Large Scale: tool dict with 1000 keys, underscore_case key present
    tool = {f"key_{i}": i for i in range(1000)}
    tool["code_execution"] = {"result": 2002}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.95μs -> 2.81μs (5.09% faster)

def test_large_tool_dict_neither_key_present(config):
    # Large Scale: tool dict with 1000 keys, neither key present
    tool = {f"randomKey{i}": i for i in range(1000)}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.90μs -> 2.69μs (7.77% faster)

def test_large_tool_dict_both_keys_present(config):
    # Large Scale: tool dict with 999 dummy keys, both camelCase and underscore_case present
    tool = {f"foo{i}": i for i in range(999)}
    tool["codeExecution"] = {"result": 123}
    tool["code_execution"] = {"result": 456}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.71μs -> 2.41μs (12.7% faster)

def test_large_tool_dict_key_at_end(config):
    # Large Scale: tool dict with 999 dummy keys, camelCase key at the end
    tool = {f"foo{i}": i for i in range(999)}
    tool["codeExecution"] = {"result": 789}
    codeflash_output = config.get_tool_value(tool, "codeExecution") # 2.77μs -> 2.41μs (14.9% 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-VertexGeminiConfig.get_tool_value-mhodwf6b and push.

Codeflash Static Badge

The optimized code achieves a **9% speedup** through two key optimizations:

**1. `__init__` Method Optimization:**
The original code used `locals().copy()` and iterated through all local variables, which creates unnecessary overhead. The optimized version directly checks each parameter individually with explicit `if` statements, avoiding dictionary creation and iteration. This is more efficient since most parameters are typically `None` during initialization.

**2. `get_tool_value` Method Optimization:**
- **Eliminated redundant dictionary lookups**: The original code called `tool.get()` multiple times for the same key. The optimized version stores the result in a variable and reuses it, reducing dictionary access overhead.
- **Improved string conversion logic**: Instead of using a list comprehension with conditional expressions inside `"".join()`, the optimized version uses a simple loop with explicit character appending, which is more efficient for string building operations.

**Performance Benefits by Test Case:**
- **Short strings** (empty, single char): Show the largest improvements (26-55% faster) due to reduced overhead
- **Complex camelCase conversions**: Moderate improvements (3-15% faster) from more efficient string processing
- **Large dictionaries**: Consistent 5-15% improvements from reduced dictionary lookups
- **Error cases**: 5-20% faster due to streamlined execution paths

The optimizations are particularly effective for frequently called utility functions like `get_tool_value`, which appears to be used extensively in tool configuration scenarios. The improvements scale well with both simple and complex inputs while maintaining identical functionality.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 November 7, 2025 04:57
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: Medium Optimization Quality according to Codeflash labels Nov 7, 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: Medium Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant