Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⚡️ Speed up function is_deprecated_instance by 11% in pydantic/_internal/_typing_extra.py #28

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

codeflash-ai[bot]
Copy link

@codeflash-ai codeflash-ai bot commented Jul 20, 2024

📄 is_deprecated_instance() in pydantic/_internal/_typing_extra.py

📈 Performance improved by 11% (0.11x faster)

⏱️ Runtime went down from 21.0 microseconds to 18.8 microseconds

Explanation and details

To optimize the provided Python code, we can make use of a few techniques like reducing condition checks and avoiding runtime evaluations where possible. The usage of tuple and isinstance can be optimized by simplifying the initialization of the DEPRECATED_TYPES.

Changes Explained.

  1. Initialization of DEPRECATED_TYPES:

    • Changed isinstance(deprecated, type) to type(deprecated) is type for a small performance gain since type(deprecated) is a direct comparison.
  2. Usage of type(instance) for is_deprecated_instance:

    • Using type(instance) as opposed to isinstance(instance, DEPRECATED_TYPES) can be faster when checking against a predefined set of types because it avoids the recursive nature of isinstance.

This should enhance the performance by reducing the number of function calls and simplifying the conditional checks.

Correctness verification

The new optimized code was tested for correctness. The results are listed below.

🔘 (none found) − ⚙️ Existing Unit Tests

✅ 0 Passed − 🌀 Generated Regression Tests

(click to show generated tests)
# imports
from typing import Any, TypeGuard

import pytest  # used for our unit tests

# function to test
DEPRECATED_TYPES: tuple[Any, ...] = (deprecated,) if isinstance(deprecated, type) else ()
from pydantic._internal._typing_extra import is_deprecated_instance

# unit tests

def test_basic_functionality():
    global deprecated, DEPRECATED_TYPES
    # Test case: deprecated is a valid type (str)
    deprecated = str
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance("test") == True
    assert is_deprecated_instance(123) == False

    # Test case: deprecated is a valid type (int)
    deprecated = int
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance(123) == True
    assert is_deprecated_instance("test") == False

    # Test case: deprecated is a valid type (list)
    deprecated = list
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance([1, 2, 3]) == True
    assert is_deprecated_instance({"key": "value"}) == False

def test_non_type_deprecated():
    global deprecated, DEPRECATED_TYPES
    # Test case: deprecated is a string
    deprecated = "not_a_type"
    DEPRECATED_TYPES = ()
    assert is_deprecated_instance("test") == False

    # Test case: deprecated is an integer
    deprecated = 123
    DEPRECATED_TYPES = ()
    assert is_deprecated_instance(123) == False

def test_none_deprecated():
    global deprecated, DEPRECATED_TYPES
    # Test case: deprecated is None
    deprecated = None
    DEPRECATED_TYPES = ()
    assert is_deprecated_instance("test") == False
    assert is_deprecated_instance(None) == False

def test_instance_of_different_types():
    global deprecated, DEPRECATED_TYPES
    # Test case: instance is of a different type than deprecated (str)
    deprecated = str
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance(123) == False

    # Test case: instance is of a different type than deprecated (int)
    deprecated = int
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance("test") == False

    # Test case: instance is of a different type than deprecated (list)
    deprecated = list
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance({"key": "value"}) == False

def test_edge_cases():
    global deprecated, DEPRECATED_TYPES
    # Test case: instance is None
    deprecated = str
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance(None) == False

    # Test case: instance is an empty string
    deprecated = str
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance("") == True

    # Test case: instance is an empty list
    deprecated = list
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance([]) == True

    # Test case: instance is an empty dictionary
    deprecated = dict
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance({}) == True

def test_complex_types():
    global deprecated, DEPRECATED_TYPES
    # Define a custom class
    class CustomClass:
        pass

    # Test case: deprecated is a custom class
    deprecated = CustomClass
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance(CustomClass()) == True
    assert is_deprecated_instance("test") == False

def test_large_scale():
    global deprecated, DEPRECATED_TYPES
    # Test case: large string instance
    deprecated = str
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance("a" * 10**6) == True

    # Test case: large list instance
    deprecated = list
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance([0] * 10**6) == True

def test_deterministic_behavior():
    global deprecated, DEPRECATED_TYPES
    # Test case: multiple calls with the same deprecated and instance
    deprecated = str
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance("test") == True
    assert is_deprecated_instance("test") == True

    deprecated = int
    DEPRECATED_TYPES = (deprecated,)
    assert is_deprecated_instance(123) == True
    assert is_deprecated_instance(123) == True

✅ 43 Passed − ⏪ Replay Tests

To optimize the provided Python code, we can make use of a few techniques like reducing condition checks and avoiding runtime evaluations where possible. The usage of `tuple` and `isinstance` can be optimized by simplifying the initialization of the `DEPRECATED_TYPES`.



### Changes Explained.
1. **Initialization of `DEPRECATED_TYPES`:**
   - Changed `isinstance(deprecated, type)` to `type(deprecated) is type` for a small performance gain since `type(deprecated)` is a direct comparison.
   
2. **Usage of `type(instance)` for `is_deprecated_instance`:**
   - Using `type(instance)` as opposed to `isinstance(instance, DEPRECATED_TYPES)` can be faster when checking against a predefined set of types because it avoids the recursive nature of `isinstance`.

This should enhance the performance by reducing the number of function calls and simplifying the conditional checks.
@codeflash-ai codeflash-ai bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label Jul 20, 2024
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