Skip to content

⚡️ Speed up function function_kind by 93% #323

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

Open
wants to merge 1 commit into
base: updated-vsc-extension
Choose a base branch
from

Conversation

codeflash-ai[bot]
Copy link
Contributor

@codeflash-ai codeflash-ai bot commented Jun 12, 2025

📄 93% (0.93x) speedup for function_kind in codeflash/code_utils/static_analysis.py

⏱️ Runtime : 1.95 milliseconds 1.01 milliseconds (best of 63 runs)

📝 Explanation and details

Here's an optimized rewrite of your function for both runtime and memory, based on the line profiler output and your code.

Key optimizations:

  • Remove the pointless loop (for _i in range(len(parents) - 1, -1, -1): continue), which does nothing but waste time.
  • Replace parents[0].type in ["FunctionDef", "AsyncFunctionDef"] with a more efficient set membership {...}.
  • Check parents and parents[0].type == "ClassDef" directly (avoid double-checking parents).
  • Avoid repeated attribute lookups.
  • Short-circuit decorator search using a set, and prefer "class" checks before "static", as the order of checks is clear by code frequency.
  • Use early returns.
  • You can even use a for loop with an else to avoid redundant returns.

Here’s the rewritten code.

Explanation of removed code:

  • The loop for _i in range(len(parents) - 1, -1, -1): continue was a no-op—removing it increases speed by eliminating unnecessary iterations.
  • Using a set for in {"FunctionDef", "AsyncFunctionDef"} is O(1) membership instead of O(n) in a list.

This preserves all existing comments as per your instruction.
Let me know if you want further alt optimizations or more detail!

Correctness verification report:

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

import ast
from dataclasses import dataclass
from enum import Enum
from typing import List

# imports
import pytest  # used for our unit tests
from codeflash.code_utils.static_analysis import function_kind

# --- Minimal stubs for FunctionParent and FunctionKind for testing ---

class FunctionKind(Enum):
    FUNCTION = "function"
    INSTANCE_METHOD = "instance_method"
    CLASS_METHOD = "class_method"
    STATIC_METHOD = "static_method"

@dataclass
class FunctionParent:
    type: str  # e.g. "Module", "ClassDef", "FunctionDef", "AsyncFunctionDef"
from codeflash.code_utils.static_analysis import function_kind

# --- Helper functions for test case construction ---

def make_funcdef(name="foo", decorators=None, async_=False):
    """Create a FunctionDef or AsyncFunctionDef AST node with given decorators."""
    if decorators is None:
        decorators = []
    if async_:
        node = ast.AsyncFunctionDef(
            name=name,
            args=ast.arguments(posonlyargs=[], args=[], kwonlyargs=[], kw_defaults=[], defaults=[]),
            body=[],
            decorator_list=decorators,
            returns=None,
            type_comment=None
        )
    else:
        node = ast.FunctionDef(
            name=name,
            args=ast.arguments(posonlyargs=[], args=[], kwonlyargs=[], kw_defaults=[], defaults=[]),
            body=[],
            decorator_list=decorators,
            returns=None,
            type_comment=None
        )
    return node

def make_decorator_name(name):
    """Create an ast.Name node representing a decorator."""
    return ast.Name(id=name, ctx=ast.Load())

# --- Unit tests ---

# 1. BASIC TEST CASES

def test_module_level_function():
    """Test a plain function at module level."""
    node = make_funcdef()
    parents = [FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.33μs -> 417ns

def test_module_level_async_function():
    """Test an async function at module level."""
    node = make_funcdef(async_=True)
    parents = [FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 625ns -> 417ns

def test_function_nested_in_function():
    """Test a function nested inside another function."""
    node = make_funcdef()
    parents = [FunctionParent(type="FunctionDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 792ns -> 625ns

def test_function_nested_in_async_function():
    """Test a function nested inside an async function."""
    node = make_funcdef()
    parents = [FunctionParent(type="AsyncFunctionDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 750ns -> 542ns

def test_instance_method_in_class():
    """Test a method in a class with no decorators."""
    node = make_funcdef()
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.62μs -> 708ns

def test_class_method_in_class():
    """Test a class method in a class."""
    node = make_funcdef(decorators=[make_decorator_name("classmethod")])
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.62μs -> 875ns

def test_static_method_in_class():
    """Test a static method in a class."""
    node = make_funcdef(decorators=[make_decorator_name("staticmethod")])
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.54μs -> 1.00μs

def test_method_with_multiple_decorators():
    """Test a method with multiple decorators, including classmethod and staticmethod."""
    node = make_funcdef(decorators=[
        make_decorator_name("custom_decorator"),
        make_decorator_name("classmethod")
    ])
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.92μs -> 1.04μs

def test_method_with_staticmethod_first():
    """Test a method with staticmethod as first decorator."""
    node = make_funcdef(decorators=[
        make_decorator_name("staticmethod"),
        make_decorator_name("custom_decorator")
    ])
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.58μs -> 792ns

def test_method_with_no_decorators_in_class():
    """Test a method in class with no decorators."""
    node = make_funcdef()
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.33μs -> 708ns

# 2. EDGE TEST CASES

def test_no_parents_list():
    """Test with an empty parents list (should be module-level function)."""
    node = make_funcdef()
    parents = []
    codeflash_output = function_kind(node, parents) # 709ns -> 458ns


def test_decorator_not_name():
    """Test a decorator that is not an ast.Name (e.g., ast.Attribute)."""
    decorator = ast.Attribute(value=ast.Name(id="some", ctx=ast.Load()), attr="decorator", ctx=ast.Load())
    node = make_funcdef(decorators=[decorator])
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    # Should be instance method since no classmethod/staticmethod found
    codeflash_output = function_kind(node, parents) # 2.54μs -> 1.21μs

def test_unknown_parent_type():
    """Test with an unknown parent type."""
    node = make_funcdef()
    parents = [FunctionParent(type="UnknownType"), FunctionParent(type="Module")]
    # Should return None, as not a known context
    codeflash_output = function_kind(node, parents) # 1.25μs -> 500ns

def test_function_in_nested_class():
    """Test a function inside a class inside another class."""
    node = make_funcdef()
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.58μs -> 709ns

def test_class_method_with_attribute_decorator():
    """Test a classmethod decorator written as an attribute (should not be detected)."""
    decorator = ast.Attribute(value=ast.Name(id="abc", ctx=ast.Load()), attr="classmethod", ctx=ast.Load())
    node = make_funcdef(decorators=[decorator])
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    # Should not detect as classmethod, so should be instance method
    codeflash_output = function_kind(node, parents) # 1.75μs -> 833ns

def test_static_method_with_attribute_decorator():
    """Test a staticmethod decorator written as an attribute (should not be detected)."""
    decorator = ast.Attribute(value=ast.Name(id="abc", ctx=ast.Load()), attr="staticmethod", ctx=ast.Load())
    node = make_funcdef(decorators=[decorator])
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    # Should not detect as staticmethod, so should be instance method
    codeflash_output = function_kind(node, parents) # 1.38μs -> 833ns

def test_function_with_multiple_parents():
    """Test a function nested several layers deep in classes and functions."""
    node = make_funcdef()
    parents = [
        FunctionParent(type="FunctionDef"),
        FunctionParent(type="ClassDef"),
        FunctionParent(type="ClassDef"),
        FunctionParent(type="Module")
    ]
    # Since top parent is a function, should be FUNCTION
    codeflash_output = function_kind(node, parents) # 917ns -> 625ns

def test_async_method_in_class():
    """Test an async method in a class."""
    node = make_funcdef(async_=True)
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.33μs -> 667ns

def test_class_method_and_static_method_decorators():
    """Test a method with both classmethod and staticmethod decorators (should prefer classmethod)."""
    node = make_funcdef(decorators=[
        make_decorator_name("classmethod"),
        make_decorator_name("staticmethod")
    ])
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    # Should return CLASS_METHOD because it finds classmethod first
    codeflash_output = function_kind(node, parents) # 1.58μs -> 1.00μs

def test_static_method_and_class_method_decorators():
    """Test a method with both staticmethod and classmethod decorators (should prefer staticmethod if first)."""
    node = make_funcdef(decorators=[
        make_decorator_name("staticmethod"),
        make_decorator_name("classmethod")
    ])
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    # Should return STATIC_METHOD because it finds staticmethod first
    codeflash_output = function_kind(node, parents) # 1.83μs -> 958ns

def test_function_with_empty_decorator_list():
    """Test a function with an explicitly empty decorator list."""
    node = make_funcdef(decorators=[])
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.38μs -> 667ns

# 3. LARGE SCALE TEST CASES

def test_many_module_level_functions():
    """Test many module-level functions for scalability."""
    nodes = [make_funcdef(name=f"func_{i}") for i in range(500)]
    parents = [FunctionParent(type="Module")]
    for node in nodes:
        codeflash_output = function_kind(node, parents) # 250ns -> 83ns

def test_many_class_methods_in_class():
    """Test many class methods in a class."""
    nodes = [make_funcdef(name=f"cm_{i}", decorators=[make_decorator_name("classmethod")]) for i in range(500)]
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    for node in nodes:
        codeflash_output = function_kind(node, parents) # 500ns -> 291ns

def test_many_static_methods_in_class():
    """Test many static methods in a class."""
    nodes = [make_funcdef(name=f"sm_{i}", decorators=[make_decorator_name("staticmethod")]) for i in range(500)]
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    for node in nodes:
        codeflash_output = function_kind(node, parents) # 541ns -> 292ns

def test_many_methods_with_varied_decorators():
    """Test many methods in a class with varied decorators."""
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    for i in range(0, 500, 3):
        # Every third is a classmethod, next is staticmethod, next is instance
        node1 = make_funcdef(name=f"cm_{i}", decorators=[make_decorator_name("classmethod")])
        node2 = make_funcdef(name=f"sm_{i+1}", decorators=[make_decorator_name("staticmethod")])
        node3 = make_funcdef(name=f"im_{i+2}")
        codeflash_output = function_kind(node1, parents) # 458ns -> 208ns
        codeflash_output = function_kind(node2, parents) # 458ns -> 208ns
        codeflash_output = function_kind(node3, parents) # 458ns -> 208ns

def test_large_nested_function_depth():
    """Test a function nested deeply in functions (should always be FUNCTION)."""
    node = make_funcdef()
    # 1000 nested functions
    parents = [FunctionParent(type="FunctionDef")] * 1000
    codeflash_output = function_kind(node, parents) # 1.38μs -> 667ns

def test_large_nested_class_depth():
    """Test a method nested deeply in classes (should always be INSTANCE_METHOD if no decorator)."""
    node = make_funcdef()
    # 999 nested classes, then module
    parents = [FunctionParent(type="ClassDef")] * 999 + [FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 14.1μs -> 625ns

def test_large_mixed_nesting():
    """Test a function with mixed deep nesting of classes and functions."""
    node = make_funcdef()
    # 500 functions, 499 classes, then module
    parents = [FunctionParent(type="FunctionDef")] * 500 + [FunctionParent(type="ClassDef")] * 499 + [FunctionParent(type="Module")]
    # Because the top parent is a function, should be FUNCTION
    codeflash_output = function_kind(node, parents) # 709ns -> 542ns

def test_large_list_of_static_and_class_methods():
    """Test a large number of methods with alternating staticmethod/classmethod decorators."""
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="Module")]
    for i in range(1000):
        if i % 2 == 0:
            node = make_funcdef(name=f"sm_{i}", decorators=[make_decorator_name("staticmethod")])
            codeflash_output = function_kind(node, parents) # 500ns -> 250ns
        else:
            node = make_funcdef(name=f"cm_{i}", decorators=[make_decorator_name("classmethod")])
            codeflash_output = function_kind(node, parents) # 500ns -> 250ns
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

from __future__ import annotations

import ast
from dataclasses import dataclass
from enum import Enum
from typing import List

# imports
import pytest  # used for our unit tests
from codeflash.code_utils.static_analysis import function_kind


# Mocking FunctionKind and FunctionParent for testing purposes
class FunctionKind(Enum):
    FUNCTION = "function"
    INSTANCE_METHOD = "instance_method"
    CLASS_METHOD = "class_method"
    STATIC_METHOD = "static_method"

@dataclass
class FunctionParent:
    type: str  # e.g., "ClassDef", "FunctionDef", "AsyncFunctionDef"
from codeflash.code_utils.static_analysis import function_kind


# Helper function to create a minimal ast.FunctionDef or ast.AsyncFunctionDef node
def make_func(name="f", decorators=None, async_func=False):
    if decorators is None:
        decorators = []
    args = ast.arguments(posonlyargs=[], args=[], kwonlyargs=[], kw_defaults=[], defaults=[])
    if async_func:
        return ast.AsyncFunctionDef(
            name=name,
            args=args,
            body=[],
            decorator_list=decorators,
            returns=None,
            type_comment=None
        )
    else:
        return ast.FunctionDef(
            name=name,
            args=args,
            body=[],
            decorator_list=decorators,
            returns=None,
            type_comment=None
        )

# -------------------
# Unit Tests
# -------------------

# 1. BASIC TEST CASES

def test_module_level_function():
    # No parents: module-level function
    node = make_func()
    parents = []
    codeflash_output = function_kind(node, parents) # 1.33μs -> 417ns

def test_module_level_async_function():
    # No parents: module-level async function
    node = make_func(async_func=True)
    parents = []
    codeflash_output = function_kind(node, parents) # 625ns -> 417ns

def test_nested_function():
    # Parent is a function: nested function
    node = make_func()
    parents = [FunctionParent(type="FunctionDef")]
    codeflash_output = function_kind(node, parents) # 834ns -> 666ns

def test_nested_async_function():
    # Parent is an async function: nested function
    node = make_func()
    parents = [FunctionParent(type="AsyncFunctionDef")]
    codeflash_output = function_kind(node, parents) # 917ns -> 666ns

def test_instance_method():
    # Parent is a class, no decorators: instance method
    node = make_func()
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 2.50μs -> 833ns

def test_class_method():
    # Parent is a class, with @classmethod decorator
    decorator = ast.Name(id="classmethod", ctx=ast.Load())
    node = make_func(decorators=[decorator])
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 2.00μs -> 875ns

def test_static_method():
    # Parent is a class, with @staticmethod decorator
    decorator = ast.Name(id="staticmethod", ctx=ast.Load())
    node = make_func(decorators=[decorator])
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 1.58μs -> 875ns

def test_class_method_with_multiple_decorators():
    # Parent is a class, with multiple decorators including @classmethod
    decorator1 = ast.Name(id="some_decorator", ctx=ast.Load())
    decorator2 = ast.Name(id="classmethod", ctx=ast.Load())
    node = make_func(decorators=[decorator1, decorator2])
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 1.92μs -> 1.04μs

def test_static_method_with_multiple_decorators():
    # Parent is a class, with multiple decorators including @staticmethod
    decorator1 = ast.Name(id="staticmethod", ctx=ast.Load())
    decorator2 = ast.Name(id="another", ctx=ast.Load())
    node = make_func(decorators=[decorator1, decorator2])
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 1.75μs -> 875ns

# 2. EDGE TEST CASES

def test_empty_parents():
    # parents is empty (module-level function)
    node = make_func()
    parents = []
    codeflash_output = function_kind(node, parents) # 667ns -> 458ns

def test_parents_with_unknown_type():
    # Parent is not a class or function, should return None
    node = make_func()
    parents = [FunctionParent(type="Module")]
    codeflash_output = function_kind(node, parents) # 1.12μs -> 500ns

def test_class_method_decorator_as_attribute():
    # Decorator is an attribute, not a name (should not match)
    decorator = ast.Attribute(value=ast.Name(id="abc", ctx=ast.Load()), attr="classmethod", ctx=ast.Load())
    node = make_func(decorators=[decorator])
    parents = [FunctionParent(type="ClassDef")]
    # Should be detected as instance method, since decorator is not ast.Name
    codeflash_output = function_kind(node, parents) # 1.75μs -> 917ns

def test_static_method_decorator_as_call():
    # Decorator is a call, not a name (should not match)
    decorator = ast.Call(func=ast.Name(id="staticmethod", ctx=ast.Load()), args=[], keywords=[])
    node = make_func(decorators=[decorator])
    parents = [FunctionParent(type="ClassDef")]
    # Should be detected as instance method, since decorator is not ast.Name
    codeflash_output = function_kind(node, parents) # 1.54μs -> 792ns

def test_multiple_parents_class_first():
    # Multiple parents: class is first, then function
    node = make_func()
    parents = [FunctionParent(type="ClassDef"), FunctionParent(type="FunctionDef")]
    codeflash_output = function_kind(node, parents) # 1.46μs -> 708ns

def test_multiple_parents_function_first():
    # Multiple parents: function is first, then class
    node = make_func()
    parents = [FunctionParent(type="FunctionDef"), FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 708ns -> 584ns

def test_no_decorators_in_class():
    # Parent is a class, decorator_list is empty
    node = make_func(decorators=[])
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 1.38μs -> 709ns

def test_unknown_decorator_in_class():
    # Parent is a class, decorator is unknown
    decorator = ast.Name(id="my_decorator", ctx=ast.Load())
    node = make_func(decorators=[decorator])
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 1.75μs -> 1.00μs

def test_async_method_in_class():
    # Async function in class, no decorators: instance method
    node = make_func(async_func=True)
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 1.33μs -> 667ns

def test_async_class_method():
    # Async function in class, with @classmethod
    decorator = ast.Name(id="classmethod", ctx=ast.Load())
    node = make_func(decorators=[decorator], async_func=True)
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 1.79μs -> 833ns

def test_async_static_method():
    # Async function in class, with @staticmethod
    decorator = ast.Name(id="staticmethod", ctx=ast.Load())
    node = make_func(decorators=[decorator], async_func=True)
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 1.67μs -> 875ns

def test_classdef_parent_but_not_first():
    # ClassDef is not the first parent, should not be treated as method
    node = make_func()
    parents = [FunctionParent(type="FunctionDef"), FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 750ns -> 542ns

def test_unexpected_parent_types():
    # Unexpected parent types, should return None
    node = make_func()
    parents = [FunctionParent(type="Module"), FunctionParent(type="Whatever")]
    codeflash_output = function_kind(node, parents) # 1.25μs -> 500ns


def test_decorator_case_sensitivity():
    # Decorator is 'ClassMethod' (case sensitive, should not match)
    decorator = ast.Name(id="ClassMethod", ctx=ast.Load())
    node = make_func(decorators=[decorator])
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 1.92μs -> 917ns

# 3. LARGE SCALE TEST CASES

def test_large_number_of_parents_module_level():
    # Large parents list, but all are functions: should be FUNCTION
    node = make_func()
    parents = [FunctionParent(type="FunctionDef")] * 500
    codeflash_output = function_kind(node, parents) # 666ns -> 625ns

def test_large_number_of_parents_with_class_first():
    # Large parents list, first is ClassDef: should be INSTANCE_METHOD
    node = make_func()
    parents = [FunctionParent(type="ClassDef")] + [FunctionParent(type="FunctionDef")] * 999
    codeflash_output = function_kind(node, parents) # 14.1μs -> 708ns

def test_large_number_of_parents_with_unknown_first():
    # Large parents list, first is unknown type: should return None
    node = make_func()
    parents = [FunctionParent(type="Unknown")] + [FunctionParent(type="ClassDef")] * 999
    codeflash_output = function_kind(node, parents) # 12.5μs -> 458ns

def test_large_decorator_list_with_classmethod():
    # Large decorator list, classmethod is at the end
    decorators = [ast.Name(id=f"decorator_{i}", ctx=ast.Load()) for i in range(998)]
    decorators.append(ast.Name(id="classmethod", ctx=ast.Load()))
    node = make_func(decorators=decorators)
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 69.6μs -> 48.9μs

def test_large_decorator_list_with_staticmethod():
    # Large decorator list, staticmethod is at the beginning
    decorators = [ast.Name(id="staticmethod", ctx=ast.Load())] + [ast.Name(id=f"decorator_{i}", ctx=ast.Load()) for i in range(998)]
    node = make_func(decorators=decorators)
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 1.83μs -> 958ns

def test_large_decorator_list_no_special_method():
    # Large decorator list, none are classmethod/staticmethod
    decorators = [ast.Name(id=f"decorator_{i}", ctx=ast.Load()) for i in range(1000)]
    node = make_func(decorators=decorators)
    parents = [FunctionParent(type="ClassDef")]
    codeflash_output = function_kind(node, parents) # 72.1μs -> 50.7μs

def test_large_scale_async_functions():
    # Large number of async functions, all as module-level
    for i in range(100):
        node = make_func(name=f"f_{i}", async_func=True)
        parents = []
        codeflash_output = function_kind(node, parents) # 166ns -> 125ns

def test_large_scale_nested_functions():
    # Deeply nested functions (up to 1000), should always be FUNCTION
    node = make_func()
    parents = [FunctionParent(type="FunctionDef")] * 1000
    codeflash_output = function_kind(node, parents) # 875ns -> 625ns
# 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-function_kind-mbtnfboc and push.

Codeflash

Here's an optimized rewrite of your function for both runtime and memory, based on the line profiler output and your code.

**Key optimizations:**
- Remove the pointless loop (`for _i in range(len(parents) - 1, -1, -1): continue`), which does nothing but waste time.
- Replace `parents[0].type in ["FunctionDef", "AsyncFunctionDef"]` with a more efficient set membership `{...}`.
- Check `parents and parents[0].type == "ClassDef"` directly (avoid double-checking parents).
- Avoid repeated attribute lookups.
- Short-circuit decorator search using a set, and prefer "class" checks before "static", as the order of checks is clear by code frequency.
- Use early returns.
- You can even use a `for` loop with an `else` to avoid redundant returns.

Here’s the rewritten code.



**Explanation of removed code:**
- The loop `for _i in range(len(parents) - 1, -1, -1): continue` was a no-op—removing it increases speed by eliminating unnecessary iterations.
- Using a set for `in {"FunctionDef", "AsyncFunctionDef"}` is O(1) membership instead of O(n) in a list.

**This preserves all existing comments as per your instruction.**  
Let me know if you want further alt optimizations or more detail!
@codeflash-ai codeflash-ai bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label Jun 12, 2025
@codeflash-ai codeflash-ai bot requested a review from KRRT7 June 12, 2025 17:24
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