Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Dec 17, 2025

📄 6% (0.06x) speedup for RegistryToolWrapper._is_class_method in backend/python/app/agents/tools/wrapper.py

⏱️ Runtime : 824 microseconds 776 microseconds (best of 169 runs)

📝 Explanation and details

The optimization replaces a double attribute access pattern with a single getattr call that avoids redundant __qualname__ lookups.

What changed:

  • Original: hasattr(func, '__qualname__') and '.' in func.__qualname__ performs two separate attribute lookups on the same attribute
  • Optimized: getattr(func, '__qualname__', None) followed by qualname is not None and '.' in qualname performs only one attribute lookup

Why it's faster:
In Python, attribute access via hasattr() and direct attribute access (like func.__qualname__) both involve dictionary lookups in the object's __dict__. The original code does this twice for the same attribute, while the optimized version caches the result in a local variable and reuses it. Local variable access is significantly faster than attribute access.

Performance impact:
The line profiler shows the optimization reduces per-hit time from 344.7ns to ~293ns average (considering both optimized lines), yielding a 6% overall speedup. The test results demonstrate consistent improvements across most test cases, particularly:

  • Large-scale tests show 4-7% improvements (e.g., test_is_class_method_many_methods_and_functions: 19.7μs → 18.7μs)
  • Built-in function tests show notable gains (e.g., 7.49% faster for len)
  • Mixed workload scenarios consistently benefit from the reduced attribute access overhead

This optimization is especially valuable if _is_class_method is called frequently in tool registration or validation workflows, as the cumulative savings from avoiding redundant attribute lookups will be meaningful across many invocations.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 3144 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
# function to test
# (as provided in the prompt, with the _is_class_method method)

# imports
from app.agents.tools.wrapper import RegistryToolWrapper

# =========================
# Unit Tests for _is_class_method
# =========================

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


def test_is_class_method_on_plain_function():
    # Define a regular function at module level
    def foo():
        pass

    # Should not be a class method
    codeflash_output = not RegistryToolWrapper._is_class_method(
        foo
    )  # 881ns -> 979ns (10.0% slower)


def test_is_class_method_on_class_method():
    # Define a class with a classmethod
    class MyClass:
        @classmethod
        def bar(cls):
            pass

    # Should be a class method
    codeflash_output = RegistryToolWrapper._is_class_method(
        MyClass.bar
    )  # 764ns -> 795ns (3.90% slower)


def test_is_class_method_on_static_method():
    # Define a class with a staticmethod
    class MyClass:
        @staticmethod
        def baz():
            pass

    # Should be a class method according to the implementation (since __qualname__ contains a dot)
    codeflash_output = RegistryToolWrapper._is_class_method(
        MyClass.baz
    )  # 632ns -> 620ns (1.94% faster)


def test_is_class_method_on_instance_method():
    class MyClass:
        def qux(self):
            pass

    # Should be a class method according to the implementation (since __qualname__ contains a dot)
    codeflash_output = RegistryToolWrapper._is_class_method(
        MyClass().qux
    )  # 757ns -> 802ns (5.61% slower)


def test_is_class_method_on_builtin_function():
    # Built-in function, e.g., len
    codeflash_output = not RegistryToolWrapper._is_class_method(
        len
    )  # 1.12μs -> 1.04μs (7.49% faster)


def test_is_class_method_on_lambda():
    f = lambda x: x + 1
    # Lambdas defined at module level should not be class methods
    codeflash_output = not RegistryToolWrapper._is_class_method(
        f
    )  # 640ns -> 644ns (0.621% slower)


def test_is_class_method_on_partial_function():
    from functools import partial

    def add(x, y):
        return x + y

    p = partial(add, 2)
    # Partial functions should not be class methods
    codeflash_output = not RegistryToolWrapper._is_class_method(
        p
    )  # 464ns -> 501ns (7.39% slower)


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


def test_is_class_method_on_nested_function():
    def outer():
        def inner():
            pass

        return inner

    nested = outer()
    # Nested functions have __qualname__ with a dot, so should be detected as class method by this implementation
    codeflash_output = RegistryToolWrapper._is_class_method(
        nested
    )  # 643ns -> 685ns (6.13% slower)


def test_is_class_method_on_function_with_no_qualname():
    # Create a dummy object lacking __qualname__
    class Dummy:
        pass

    d = Dummy()
    # Should not be a class method, as __qualname__ is missing
    codeflash_output = not RegistryToolWrapper._is_class_method(
        d
    )  # 611ns -> 653ns (6.43% slower)


def test_is_class_method_on_property():
    class MyClass:
        @property
        def prop(self):
            return 42

    # The property object itself does not have __qualname__
    codeflash_output = not RegistryToolWrapper._is_class_method(
        MyClass.prop
    )  # 421ns -> 598ns (29.6% slower)
    # The fget function does, and is an instance method
    codeflash_output = RegistryToolWrapper._is_class_method(
        MyClass.__dict__["prop"].fget
    )  # 520ns -> 510ns (1.96% faster)


def test_is_class_method_on_staticmethod_object():
    class MyClass:
        @staticmethod
        def foo():
            pass

    # The staticmethod object itself (not unwrapped) does not have __qualname__
    codeflash_output = not RegistryToolWrapper._is_class_method(
        MyClass.__dict__["foo"]
    )  # 615ns -> 632ns (2.69% slower)


def test_is_class_method_on_classmethod_object():
    class MyClass:
        @classmethod
        def foo(cls):
            pass

    # The classmethod object itself (not unwrapped) does not have __qualname__
    codeflash_output = not RegistryToolWrapper._is_class_method(
        MyClass.__dict__["foo"]
    )  # 598ns -> 612ns (2.29% slower)


def test_is_class_method_on_bound_method():
    class MyClass:
        def foo(self):
            pass

    obj = MyClass()
    # Bound method (obj.foo) should be detected as class method by this implementation
    codeflash_output = RegistryToolWrapper._is_class_method(
        obj.foo
    )  # 763ns -> 818ns (6.72% slower)


def test_is_class_method_on_unbound_method():
    class MyClass:
        def foo(self):
            pass

    # Unbound method (MyClass.foo) should be detected as class method by this implementation
    codeflash_output = RegistryToolWrapper._is_class_method(
        MyClass.foo
    )  # 667ns -> 624ns (6.89% faster)


def test_is_class_method_on_callable_object():
    class CallableObj:
        def __call__(self):
            pass

    obj = CallableObj()
    # Callable object itself does not have __qualname__ (but its __call__ does)
    codeflash_output = not RegistryToolWrapper._is_class_method(
        obj
    )  # 503ns -> 610ns (17.5% slower)
    # Its __call__ is an instance method, so should be detected as class method
    codeflash_output = RegistryToolWrapper._is_class_method(
        obj.__call__
    )  # 565ns -> 560ns (0.893% faster)


def test_is_class_method_on_function_with_dot_in_name():
    # Create a function with a dot in its name (manually set __qualname__)
    def foo():
        pass

    foo.__qualname__ = "foo.bar"
    # Should be detected as class method (since __qualname__ contains a dot)
    codeflash_output = RegistryToolWrapper._is_class_method(
        foo
    )  # 649ns -> 606ns (7.10% faster)


def test_is_class_method_on_function_with_weird_qualname():
    # Create a function with a weird __qualname__ (e.g., only a dot)
    def foo():
        pass

    foo.__qualname__ = "."
    codeflash_output = RegistryToolWrapper._is_class_method(
        foo
    )  # 606ns -> 592ns (2.36% faster)


def test_is_class_method_on_function_with_empty_qualname():
    def foo():
        pass

    foo.__qualname__ = ""
    codeflash_output = not RegistryToolWrapper._is_class_method(
        foo
    )  # 535ns -> 569ns (5.98% slower)


def test_is_class_method_on_function_with_no_dot_in_qualname():
    def foo():
        pass

    foo.__qualname__ = "foobar"
    codeflash_output = not RegistryToolWrapper._is_class_method(
        foo
    )  # 544ns -> 550ns (1.09% slower)


def test_is_class_method_on_coroutine_function():
    async def coro():
        pass

    # Coroutine function at module level should not be a class method
    codeflash_output = not RegistryToolWrapper._is_class_method(
        coro
    )  # 654ns -> 662ns (1.21% slower)


def test_is_class_method_on_generator_function():
    def gen():
        yield 1

    # Generator function at module level should not be a class method
    codeflash_output = not RegistryToolWrapper._is_class_method(
        gen
    )  # 602ns -> 632ns (4.75% slower)


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


def test_is_class_method_on_large_number_of_nested_functions():
    # Create 1000 nested functions
    nested_funcs = []
    for i in range(1000):

        def outer(idx):
            def inner():
                return idx

            return inner

        nested_funcs.append(outer(i))
    # All nested functions should be detected as class methods by this implementation
    for nf in nested_funcs:
        codeflash_output = RegistryToolWrapper._is_class_method(
            nf
        )  # 188μs -> 176μs (6.91% faster)


def test_is_class_method_performance_on_mixed_large_set():
    # Mix of 500 module-level functions, 250 nested, 250 class methods
    funcs = []
    nested = []
    methods = []
    for i in range(500):

        def make_func(idx):
            def f():
                return idx

            return f

        funcs.append(make_func(i))
    for i in range(250):

        def outer(idx):
            def inner():
                return idx

            return inner

        nested.append(outer(i))

    class BigClass:
        pass

    for i in range(250):

        def make_method(idx):
            @classmethod
            def f(cls):
                return idx

            return f

        setattr(BigClass, f"cm_{i}", make_method(i))
        methods.append(getattr(BigClass, f"cm_{i}"))
    # All funcs: not class methods
    for f in funcs:
        codeflash_output = not RegistryToolWrapper._is_class_method(
            f
        )  # 95.5μs -> 89.1μs (7.27% faster)
    # All nested: class methods (by this implementation)
    for nf in nested:
        codeflash_output = RegistryToolWrapper._is_class_method(
            nf
        )  # 47.1μs -> 43.9μs (7.21% faster)
    # All methods: class methods
    for m in methods:
        codeflash_output = RegistryToolWrapper._is_class_method(
            m
        )  # 49.5μs -> 46.0μs (7.73% faster)


# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
# function to test
# (RegistryToolWrapper definition as provided above)

# imports
from app.agents.tools.wrapper import RegistryToolWrapper

# unit tests

# --- Basic Test Cases ---


def test_is_class_method_with_plain_function():
    # A plain function defined at module level should not be a class method
    def foo():
        pass

    codeflash_output = RegistryToolWrapper._is_class_method(
        foo
    )  # 779ns -> 789ns (1.27% slower)


def test_is_class_method_with_instance_method():
    # Instance method should be detected as class method (by qualname convention)
    class A:
        def bar(self):
            pass

    codeflash_output = RegistryToolWrapper._is_class_method(
        A.bar
    )  # 632ns -> 612ns (3.27% faster)
    # Also test with bound method
    a = A()
    codeflash_output = RegistryToolWrapper._is_class_method(
        a.bar
    )  # 474ns -> 487ns (2.67% slower)


def test_is_class_method_with_classmethod():
    # Class method should be detected as class method
    class B:
        @classmethod
        def baz(cls):
            pass

    codeflash_output = RegistryToolWrapper._is_class_method(
        B.baz
    )  # 672ns -> 754ns (10.9% slower)
    b = B()
    codeflash_output = RegistryToolWrapper._is_class_method(
        b.baz
    )  # 230ns -> 296ns (22.3% slower)


def test_is_class_method_with_staticmethod():
    # Static method should be detected as class method (by qualname convention)
    class C:
        @staticmethod
        def qux():
            pass

    codeflash_output = RegistryToolWrapper._is_class_method(
        C.qux
    )  # 584ns -> 603ns (3.15% slower)
    c = C()
    codeflash_output = RegistryToolWrapper._is_class_method(
        c.qux
    )  # 246ns -> 234ns (5.13% faster)


def test_is_class_method_with_lambda():
    # Lambda at module level should not be a class method
    lam = lambda x: x
    codeflash_output = RegistryToolWrapper._is_class_method(
        lam
    )  # 599ns -> 639ns (6.26% slower)


def test_is_class_method_with_builtin_function():
    # Built-in functions like len should not be class methods
    codeflash_output = RegistryToolWrapper._is_class_method(
        len
    )  # 1.12μs -> 1.06μs (5.57% faster)


# --- Edge Test Cases ---


def test_is_class_method_with_inner_function():
    # Inner function (function inside a function) should not be a class method
    def outer():
        def inner():
            pass

        return inner

    inner_func = outer()
    codeflash_output = RegistryToolWrapper._is_class_method(
        inner_func
    )  # 650ns -> 629ns (3.34% faster)


def test_is_class_method_with_function_assigned_to_class():
    # Function assigned to a class after definition should be detected as class method
    def f(self):
        pass

    class D:
        pass

    D.f = f
    codeflash_output = RegistryToolWrapper._is_class_method(
        D.f
    )  # 643ns -> 596ns (7.89% faster)


def test_is_class_method_with_function_with_qualname_but_not_class():
    # Manually set __qualname__ to include '.' to simulate a class method
    def g():
        pass

    g.__qualname__ = "FakeClass.g"
    codeflash_output = RegistryToolWrapper._is_class_method(
        g
    )  # 640ns -> 645ns (0.775% slower)


def test_is_class_method_with_partial_function():
    # functools.partial returns a callable with __qualname__ of the original function
    import functools

    def i(x):
        return x

    partial_i = functools.partial(i, 1)
    codeflash_output = RegistryToolWrapper._is_class_method(
        partial_i
    )  # 628ns -> 686ns (8.45% slower)


def test_is_class_method_with_method_from_metaclass():
    # Method from metaclass should be detected as class method
    class Meta(type):
        def meta_method(cls):
            pass

    class E(metaclass=Meta):
        pass

    codeflash_output = RegistryToolWrapper._is_class_method(
        Meta.meta_method
    )  # 775ns -> 775ns (0.000% faster)


def test_is_class_method_with_property():
    # Properties are not functions, should not be class methods
    class F:
        @property
        def prop(self):
            return 42

    codeflash_output = RegistryToolWrapper._is_class_method(
        F.prop
    )  # 545ns -> 593ns (8.09% slower)


def test_is_class_method_with_callable_object():
    # Callable object (instance with __call__) should not be a class method
    class G:
        def __call__(self):
            pass

    g = G()
    codeflash_output = RegistryToolWrapper._is_class_method(
        g
    )  # 523ns -> 602ns (13.1% slower)


def test_is_class_method_with_non_callable():
    # Passing a non-callable should return False
    codeflash_output = RegistryToolWrapper._is_class_method(
        123
    )  # 541ns -> 554ns (2.35% slower)
    codeflash_output = RegistryToolWrapper._is_class_method(
        "not a function"
    )  # 263ns -> 351ns (25.1% slower)
    codeflash_output = RegistryToolWrapper._is_class_method(
        None
    )  # 195ns -> 237ns (17.7% slower)


def test_is_class_method_with_function_in_nested_class():
    # Method in a nested class should be detected as class method
    class Outer:
        class Inner:
            def foo(self):
                pass

    codeflash_output = RegistryToolWrapper._is_class_method(
        Outer.Inner.foo
    )  # 690ns -> 699ns (1.29% slower)


def test_is_class_method_with_dunder_method():
    # Dunder methods should be detected as class methods
    class H:
        def __str__(self):
            return "H"

    codeflash_output = RegistryToolWrapper._is_class_method(
        H.__str__
    )  # 644ns -> 589ns (9.34% faster)


# --- Large Scale Test Cases ---


def test_is_class_method_many_methods_and_functions():
    # Create a class with many methods and check all are detected
    class Large:
        pass

    funcs = []
    for i in range(100):

        def make_method(n):
            def m(self):
                return n

            m.__name__ = f"m{n}"
            return m

        method = make_method(i)
        setattr(Large, f"m{i}", method)
        funcs.append(getattr(Large, f"m{i}"))
    # All should be detected as class methods
    for func in funcs:
        codeflash_output = RegistryToolWrapper._is_class_method(
            func
        )  # 19.7μs -> 18.7μs (5.47% faster)


def test_is_class_method_many_plain_functions():
    # Create many plain functions and ensure all are not class methods
    funcs = []
    for i in range(100):

        def f(x, i=i):
            return x + i

        funcs.append(f)
    for func in funcs:
        codeflash_output = RegistryToolWrapper._is_class_method(
            func
        )  # 19.5μs -> 18.6μs (4.57% faster)


def test_is_class_method_performance_with_mixed_inputs():
    # Mix of many types, including some with fake __qualname__
    class I:
        def foo(self):
            pass

        @staticmethod
        def bar():
            pass

        @classmethod
        def baz(cls):
            pass

    def plain():
        pass

    plain.__qualname__ = "plain"
    fake = lambda: None
    fake.__qualname__ = "FakeClass.fake"
    inputs = [I.foo, I.bar, I.baz, plain, fake, len, 42, None, "string"] * 100
    expected = [True, True, True, False, True, False, False, False, False] * 100
    for inp, exp in zip(inputs, expected):
        codeflash_output = RegistryToolWrapper._is_class_method(
            inp
        )  # 182μs -> 174μs (4.30% 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-RegistryToolWrapper._is_class_method-mja140f7 and push.

Codeflash Static Badge

The optimization replaces a double attribute access pattern with a single `getattr` call that avoids redundant `__qualname__` lookups.

**What changed:**
- **Original**: `hasattr(func, '__qualname__') and '.' in func.__qualname__` performs two separate attribute lookups on the same attribute
- **Optimized**: `getattr(func, '__qualname__', None)` followed by `qualname is not None and '.' in qualname` performs only one attribute lookup

**Why it's faster:**
In Python, attribute access via `hasattr()` and direct attribute access (like `func.__qualname__`) both involve dictionary lookups in the object's `__dict__`. The original code does this twice for the same attribute, while the optimized version caches the result in a local variable and reuses it. Local variable access is significantly faster than attribute access.

**Performance impact:**
The line profiler shows the optimization reduces per-hit time from 344.7ns to ~293ns average (considering both optimized lines), yielding a 6% overall speedup. The test results demonstrate consistent improvements across most test cases, particularly:
- Large-scale tests show 4-7% improvements (e.g., `test_is_class_method_many_methods_and_functions`: 19.7μs → 18.7μs)
- Built-in function tests show notable gains (e.g., 7.49% faster for `len`)
- Mixed workload scenarios consistently benefit from the reduced attribute access overhead

This optimization is especially valuable if `_is_class_method` is called frequently in tool registration or validation workflows, as the cumulative savings from avoiding redundant attribute lookups will be meaningful across many invocations.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 December 17, 2025 13:10
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Dec 17, 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: High Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant