Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Apr 29, 2025

📄 340% (3.40x) speedup for ArgModelBase.model_dump_one_level in src/mcp/server/fastmcp/utilities/func_metadata.py

⏱️ Runtime : 78.5 microseconds 17.9 microseconds (best of 215 runs)

📝 Explanation and details

Here is an optimized version of your program.
The original code loops over self.__class__.model_fields.keys() and uses getattr(self, field_name).
This can be optimized by directly using self.__dict__ to avoid the attribute lookup overhead in a tight loop.
This will also avoid creating a new dict and inserting keys one by one.

Optimized code:

Key Points:

  • self.__dict__ contains the model's fields and their current values.
  • self.__dict__.copy() returns a shallow copy, matching your original behavior (returns a new dict).
  • This method is significantly faster than repeated getattr and looping through the keys.
  • It still only goes one level deep: sub-models etc. remain as pydantic models.

Behavior is the same as before, just much more efficient!

Correctness verification report:

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

# imports
import pytest  # used for our unit tests
from pydantic import BaseModel, ConfigDict
from src.mcp.server.fastmcp.utilities.func_metadata import ArgModelBase

# unit tests

# Basic Test: Simple Model with Primitive Types
def test_simple_model():
    class SimpleModel(ArgModelBase):
        name: str
        age: int
        active: bool

    model = SimpleModel(name="test", age=30, active=True)
    codeflash_output = model.model_dump_one_level()

# Basic Test: Model with Optional Fields
def test_optional_fields():
    class OptionalModel(ArgModelBase):
        name: str
        age: int = None

    model = OptionalModel(name="test")
    codeflash_output = model.model_dump_one_level()

# Complex Types: Model with List and Dict Fields
def test_list_and_dict_fields():
    class ComplexModel(ArgModelBase):
        tags: List[str]
        metadata: Dict[str, str]

    model = ComplexModel(tags=["python", "testing"], metadata={"key": "value"})
    codeflash_output = model.model_dump_one_level()

# Complex Types: Model with Custom Types
def test_custom_types():
    class CustomType:
        pass

    class CustomModel(ArgModelBase):
        custom_field: CustomType

    custom_instance = CustomType()
    model = CustomModel(custom_field=custom_instance)
    codeflash_output = model.model_dump_one_level()

# Nested Models: Model with Nested Pydantic Models

def test_empty_model():
    class EmptyModel(ArgModelBase):
        pass

    model = EmptyModel()
    codeflash_output = model.model_dump_one_level()

# Edge Case: Model with Large Number of Fields
def test_large_number_of_fields():
    class LargeModel(ArgModelBase):
        field1: int
        field2: int
        # ... up to field1000
        field1000: int

    # Create an instance with all fields initialized
    model = LargeModel(field1=1, field2=2, field1000=1000)
    expected_output = {f"field{i}": i for i in range(1, 1001)}
    codeflash_output = model.model_dump_one_level()

# Performance and Scalability: Large Scale Test Case
def test_large_scale():
    class LargeScaleModel(ArgModelBase):
        large_list: List[int]
        deep_dict: Dict[str, Dict[str, Dict[str, str]]]

    large_list = list(range(1000))
    deep_dict = {"level1": {"level2": {"level3": "value"}}}
    model = LargeScaleModel(large_list=large_list, deep_dict=deep_dict)
    codeflash_output = model.model_dump_one_level()

# Type Handling: Model with Arbitrary Types
def test_arbitrary_types():
    class SomeArbitraryType:
        pass

    class ArbitraryModel(ArgModelBase):
        arbitrary_field: SomeArbitraryType

    arbitrary_instance = SomeArbitraryType()
    model = ArbitraryModel(arbitrary_field=arbitrary_instance)
    codeflash_output = model.model_dump_one_level()

# Deterministic Behavior: Consistent Output
def test_consistent_output():
    class ConsistentModel(ArgModelBase):
        a: int
        b: int

    model1 = ConsistentModel(a=1, b=2)
    model2 = ConsistentModel(b=2, a=1)
    codeflash_output = model1.model_dump_one_level()

# Error Handling: Invalid Field Access
def test_invalid_field_access():
    class InvalidModel(ArgModelBase):
        existing_field: int

    model = InvalidModel(existing_field=42)
    with pytest.raises(AttributeError):
        getattr(model, 'non_existent_field')
# 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 Any, Dict, List

# imports
import pytest  # used for our unit tests
from pydantic import BaseModel, ConfigDict
from src.mcp.server.fastmcp.utilities.func_metadata import ArgModelBase

# unit tests

# Basic Functionality
def test_single_level_fields():
    class TestModel(ArgModelBase):
        a: int
        b: str
    
    model = TestModel(a=1, b="test")
    codeflash_output = model.model_dump_one_level()

def test_mixed_data_types():
    class TestModel(ArgModelBase):
        a: int
        b: str
        c: bool
    
    model = TestModel(a=42, b="hello", c=True)
    codeflash_output = model.model_dump_one_level()

# Nested Structures


def test_empty_model():
    class TestModel(ArgModelBase):
        pass
    
    model = TestModel()
    codeflash_output = model.model_dump_one_level()

def test_optional_fields_not_set():
    class TestModel(ArgModelBase):
        a: int = None
    
    model = TestModel()
    codeflash_output = model.model_dump_one_level()


def test_arbitrary_types():
    class CustomType:
        def __init__(self, value):
            self.value = value
    
    class TestModel(ArgModelBase):
        a: CustomType
    
    custom = CustomType(value=5)
    model = TestModel(a=custom)
    codeflash_output = model.model_dump_one_level()

def test_complex_data_structures():
    class TestModel(ArgModelBase):
        a: set
    
    model = TestModel(a={1, 2, 3})
    codeflash_output = model.model_dump_one_level()

# Large Scale Test Cases
def test_large_number_of_fields():
    class TestModel(ArgModelBase):
        a: int
        b: str
        c: float
        d: bool
        e: List[int]
    
    model = TestModel(a=1, b="large", c=3.14, d=False, e=list(range(100)))
    codeflash_output = model.model_dump_one_level()

def test_large_data_structures():
    class TestModel(ArgModelBase):
        a: Dict[str, int]
    
    large_dict = {str(i): i for i in range(1000)}
    model = TestModel(a=large_dict)
    codeflash_output = model.model_dump_one_level()

# Special Characters and Unicode
def test_special_characters():
    class TestModel(ArgModelBase):
        a: str
    
    model = TestModel(a="special!@#$%^&*()")
    codeflash_output = model.model_dump_one_level()

def test_unicode_strings():
    class TestModel(ArgModelBase):
        a: str
    
    model = TestModel(a="こんにちは")
    codeflash_output = model.model_dump_one_level()

# Immutable and Read-Only Fields
def test_immutable_fields():
    class TestModel(ArgModelBase):
        a: int
    
    model = TestModel(a=10)
    codeflash_output = model.model_dump_one_level()

def test_read_only_fields():
    class TestModel(ArgModelBase):
        a: int
    
    model = TestModel(a=20)
    codeflash_output = model.model_dump_one_level()

# Error Handling
def test_invalid_field_access():
    class TestModel(ArgModelBase):
        a: int
    
    model = TestModel(a=5)
    with pytest.raises(AttributeError):
        _ = model.model_dump_one_level()["b"]


def test_stress_test():
    class TestModel(ArgModelBase):
        a: List[int]
    
    large_list = list(range(1000))
    model = TestModel(a=large_list)
    codeflash_output = model.model_dump_one_level()
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

from src.mcp.server.fastmcp.utilities.func_metadata import ArgModelBase

def test_ArgModelBase_model_dump_one_level():
    ArgModelBase.model_dump_one_level(ArgModelBase())

To edit these changes git checkout codeflash/optimize-ArgModelBase.model_dump_one_level-ma2y3jb1 and push.

Codeflash

Here is an optimized version of your program.  
The original code loops over `self.__class__.model_fields.keys()` and uses `getattr(self, field_name)`.  
This can be optimized by directly using `self.__dict__` to avoid the attribute lookup overhead in a tight loop.  
This will also avoid creating a new dict and inserting keys one by one.

**Optimized code:**

**Key Points:**
- `self.__dict__` contains the model's fields and their current values.
- `self.__dict__.copy()` returns a shallow copy, matching your original behavior (returns a new dict).
- This method is significantly faster than repeated `getattr` and looping through the keys.
- It still only goes one level deep: sub-models etc. remain as pydantic models.

**Behavior is the same as before**, just much more efficient!
@codeflash-ai codeflash-ai bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label Apr 29, 2025
@codeflash-ai codeflash-ai bot requested a review from Saga4 April 29, 2025 20:14
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.

1 participant