langflow icon indicating copy to clipboard operation
langflow copied to clipboard

⚡️ Speed up function `set_multiple_field_advanced` by 12% in PR #7741 (`mcp-server-backend`)

Open codeflash-ai[bot] opened this issue 7 months ago • 0 comments

⚡️ This pull request contains optimizations for PR #7741

If you approve this dependent PR, these changes will be merged into the original PR branch mcp-server-backend.

This PR will be automatically closed if the original PR is merged.


📄 12% (0.12x) speedup for set_multiple_field_advanced in src/backend/base/langflow/utils/component_utils.py

⏱️ Runtime : 923 microseconds 826 microseconds (best of 114 runs)

📝 Explanation and details

To optimize the given program, we will make improvements to reduce redundant function calls and leverage direct dictionary updates where possible. Here is the revised version of the program.

Summary of Changes.

  1. Removed Redundant Function Calls:

    • In set_multiple_field_advanced, the set_field_advanced function was replaced with direct dictionary updates to avoid the overhead of repeated function calls. This helps ensure that the updates are more efficient.
  2. Avoiding Unnecessary Return in set_field_advanced:

    • The set_field_advanced function now returns None since the purpose of the function is to modify the build_config in place. This avoids confusion about needing the return value.
  3. Integrated Direct Checks within set_multiple_field_advanced:

    • The checks for the field existence and type have been integrated directly within the loops of set_multiple_field_advanced to avoid extra function calls, making the loops more efficient.

These subtle changes help to optimize both runtime and memory usage while maintaining the same functionality.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 28 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage
🌀 Generated Regression Tests Details
import pytest  # used for our unit tests
# function to test
from langflow.schema.dotdict import dotdict
from langflow.utils.component_utils import set_multiple_field_advanced


class dotdict(dict):  # noqa: N801
    """dotdict allows accessing dictionary elements using dot notation (e.g., dict.key instead of dict['key']).

    It automatically converts nested dictionaries into dotdict instances, enabling dot notation on them as well.

    Note:
        - Only keys that are valid attribute names (e.g., strings that could be variable names) are accessible via dot
          notation.
        - Keys which are not valid Python attribute names or collide with the dict method names (like 'items', 'keys')
          should be accessed using the traditional dict['key'] notation.
    """

    def __getattr__(self, attr):
        """Override dot access to behave like dictionary lookup. Automatically convert nested dicts to dotdicts.

        Args:
            attr (str): Attribute to access.

        Returns:
            The value associated with 'attr' in the dictionary, converted to dotdict if it is a dict.

        Raises:
            AttributeError: If the attribute is not found in the dictionary.
        """
        try:
            value = self[attr]
            if isinstance(value, dict) and not isinstance(value, dotdict):
                value = dotdict(value)
                self[attr] = value  # Update self to nest dotdict for future accesses
        except KeyError as e:
            msg = f"'dotdict' object has no attribute '{attr}'"
            raise AttributeError(msg) from e
        else:
            return value

    def __setattr__(self, key, value) -> None:
        """Override attribute setting to work as dictionary item assignment.

        Args:
            key (str): The key under which to store the value.
            value: The value to store in the dictionary.
        """
        if isinstance(value, dict) and not isinstance(value, dotdict):
            value = dotdict(value)
        self[key] = value

    def __delattr__(self, key) -> None:
        """Override attribute deletion to work as dictionary item deletion.

        Args:
            key (str): The key of the item to delete from the dictionary.

        Raises:
            AttributeError: If the key is not found in the dictionary.
        """
        try:
            del self[key]
        except KeyError as e:
            msg = f"'dotdict' object has no attribute '{key}'"
            raise AttributeError(msg) from e

    def __missing__(self, key):
        """Handle missing keys by returning an empty dotdict. This allows chaining access without raising KeyError.

        Args:
            key: The missing key.

        Returns:
            An empty dotdict instance for the given missing key.
        """
        return dotdict()
from langflow.utils.component_utils import set_multiple_field_advanced

# unit tests

def test_single_field_update_with_fields_dict():
    build_config = dotdict({"field1": {}})
    fields = {"field1": True}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_multiple_fields_update_with_fields_dict():
    build_config = dotdict({"field1": {}, "field2": {}})
    fields = {"field1": True, "field2": False}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_single_field_update_with_field_list():
    build_config = dotdict({"field1": {}})
    field_list = ["field1"]
    codeflash_output = set_multiple_field_advanced(build_config, field_list=field_list, is_advanced=True); result = codeflash_output

def test_multiple_fields_update_with_field_list():
    build_config = dotdict({"field1": {}, "field2": {}})
    field_list = ["field1", "field2"]
    codeflash_output = set_multiple_field_advanced(build_config, field_list=field_list, is_advanced=True); result = codeflash_output

def test_empty_fields_dict():
    build_config = dotdict({"field1": {}})
    fields = {}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_empty_field_list():
    build_config = dotdict({"field1": {}})
    field_list = []
    codeflash_output = set_multiple_field_advanced(build_config, field_list=field_list, is_advanced=True); result = codeflash_output

def test_non_existent_field_in_fields_dict():
    build_config = dotdict({"field1": {}})
    fields = {"non_existent_field": True}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_non_existent_field_in_field_list():
    build_config = dotdict({"field1": {}})
    field_list = ["non_existent_field"]
    codeflash_output = set_multiple_field_advanced(build_config, field_list=field_list, is_advanced=True); result = codeflash_output

def test_mixed_valid_and_non_existent_fields_in_fields_dict():
    build_config = dotdict({"field1": {}})
    fields = {"field1": True, "non_existent_field": False}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_mixed_valid_and_non_existent_fields_in_field_list():
    build_config = dotdict({"field1": {}})
    field_list = ["field1", "non_existent_field"]
    codeflash_output = set_multiple_field_advanced(build_config, field_list=field_list, is_advanced=True); result = codeflash_output

def test_nested_dictionaries():
    build_config = dotdict({"field1": {"nested_field": {"advanced": False}}})
    fields = {"field1.nested_field": True}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_fields_with_existing_advanced_key():
    build_config = dotdict({"field1": {"advanced": False}})
    fields = {"field1": True}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_fields_without_existing_advanced_key():
    build_config = dotdict({"field1": {}})
    fields = {"field1": True}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_large_number_of_fields_in_fields_dict():
    build_config = dotdict({f"field{i}": {} for i in range(1000)})
    fields = {f"field{i}": True for i in range(1000)}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output
    for i in range(1000):
        pass

def test_large_number_of_fields_in_field_list():
    build_config = dotdict({f"field{i}": {} for i in range(1000)})
    field_list = [f"field{i}" for i in range(1000)]
    codeflash_output = set_multiple_field_advanced(build_config, field_list=field_list, is_advanced=True); result = codeflash_output
    for i in range(1000):
        pass





import pytest  # used for our unit tests
# function to test
from langflow.schema.dotdict import dotdict
from langflow.utils.component_utils import set_multiple_field_advanced


class dotdict(dict):  # noqa: N801
    """dotdict allows accessing dictionary elements using dot notation (e.g., dict.key instead of dict['key']).

    It automatically converts nested dictionaries into dotdict instances, enabling dot notation on them as well.

    Note:
        - Only keys that are valid attribute names (e.g., strings that could be variable names) are accessible via dot
          notation.
        - Keys which are not valid Python attribute names or collide with the dict method names (like 'items', 'keys')
          should be accessed using the traditional dict['key'] notation.
    """

    def __getattr__(self, attr):
        """Override dot access to behave like dictionary lookup. Automatically convert nested dicts to dotdicts.

        Args:
            attr (str): Attribute to access.

        Returns:
            The value associated with 'attr' in the dictionary, converted to dotdict if it is a dict.

        Raises:
            AttributeError: If the attribute is not found in the dictionary.
        """
        try:
            value = self[attr]
            if isinstance(value, dict) and not isinstance(value, dotdict):
                value = dotdict(value)
                self[attr] = value  # Update self to nest dotdict for future accesses
        except KeyError as e:
            msg = f"'dotdict' object has no attribute '{attr}'"
            raise AttributeError(msg) from e
        else:
            return value

    def __setattr__(self, key, value) -> None:
        """Override attribute setting to work as dictionary item assignment.

        Args:
            key (str): The key under which to store the value.
            value: The value to store in the dictionary.
        """
        if isinstance(value, dict) and not isinstance(value, dotdict):
            value = dotdict(value)
        self[key] = value

    def __delattr__(self, key) -> None:
        """Override attribute deletion to work as dictionary item deletion.

        Args:
            key (str): The key of the item to delete from the dictionary.

        Raises:
            AttributeError: If the key is not found in the dictionary.
        """
        try:
            del self[key]
        except KeyError as e:
            msg = f"'dotdict' object has no attribute '{key}'"
            raise AttributeError(msg) from e

    def __missing__(self, key):
        """Handle missing keys by returning an empty dotdict. This allows chaining access without raising KeyError.

        Args:
            key: The missing key.

        Returns:
            An empty dotdict instance for the given missing key.
        """
        return dotdict()
from langflow.utils.component_utils import set_multiple_field_advanced

# unit tests

# Basic Functionality
def test_single_field_in_fields():
    build_config = dotdict({"field1": {}})
    fields = {"field1": True}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_multiple_fields_in_fields():
    build_config = dotdict({"field1": {}, "field2": {}})
    fields = {"field1": True, "field2": False}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

# Using field_list
def test_single_field_in_field_list():
    build_config = dotdict({"field1": {}})
    field_list = ["field1"]
    codeflash_output = set_multiple_field_advanced(build_config, field_list=field_list, is_advanced=True); result = codeflash_output

def test_multiple_fields_in_field_list():
    build_config = dotdict({"field1": {}, "field2": {}})
    field_list = ["field1", "field2"]
    codeflash_output = set_multiple_field_advanced(build_config, field_list=field_list, is_advanced=False); result = codeflash_output

# Mixed and Empty Inputs
def test_both_fields_and_field_list_none():
    build_config = dotdict({"field1": {}})
    codeflash_output = set_multiple_field_advanced(build_config, fields=None, field_list=None); result = codeflash_output

def test_fields_none_field_list_provided():
    build_config = dotdict({"field1": {}, "field2": {}})
    field_list = ["field1", "field2"]
    codeflash_output = set_multiple_field_advanced(build_config, fields=None, field_list=field_list, is_advanced=True); result = codeflash_output

def test_fields_provided_field_list_none():
    build_config = dotdict({"field1": {}})
    fields = {"field1": True}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields, field_list=None); result = codeflash_output

def test_empty_fields_and_field_list():
    build_config = dotdict({"field1": {}})
    codeflash_output = set_multiple_field_advanced(build_config, fields={}, field_list=[]); result = codeflash_output

# Edge Cases
def test_field_not_present_in_build_config():
    build_config = dotdict({})
    fields = {"non_existent_field": True}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_field_present_but_not_a_dict():
    build_config = dotdict({"field1": "not_a_dict"})
    fields = {"field1": True}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

def test_nested_fields():
    build_config = dotdict({"parent": {"child": {}}})
    fields = {"parent.child": True}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output

# Large Scale Test Cases
def test_large_number_of_fields_in_fields():
    build_config = dotdict({f"field{i}": {} for i in range(1000)})
    fields = {f"field{i}": True for i in range(1000)}
    codeflash_output = set_multiple_field_advanced(build_config, fields=fields); result = codeflash_output
    for i in range(1000):
        pass

def test_large_number_of_fields_in_field_list():
    build_config = dotdict({f"field{i}": {} for i in range(1000)})
    field_list = [f"field{i}" for i in range(1000)]
    codeflash_output = set_multiple_field_advanced(build_config, field_list=field_list, is_advanced=True); result = codeflash_output
    for i in range(1000):
        pass
# 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-pr7741-2025-04-24T07.39.46 and push.

Codeflash

codeflash-ai[bot] avatar Apr 24 '25 07:04 codeflash-ai[bot]