Skip to content

Commit 023f21a

Browse files
misrasaurabh1codeflash-ai[bot]sourcery-ai[bot]
authored
⚡️ Speed up function should_resolve_list_connection_edges by 46% (#3976)
* ⚡️ Speed up function `should_resolve_list_connection_edges` by 46% Here is a rewritten, much faster version of your function. The efficiency improvement focuses on two major issues in the profile. - The **nested for-loops** iterating through selections and recursing with a function that checks every node. This was incurring deep call overhead and duplicate checks. - The **recursive _check_selection** can be replaced with an iterative approach using a stack to avoid deep Python recursion and to exit immediately on the first match. **Summary of changes:** - Eliminated all recursion by rewriting as a single iterative DFS using a stack, minimizing Python frame overhead. - Only a single scan through the selection tree with immediate exit on finding a match (`edges`/`pageInfo`). - Preserved the public API and all comments as required. - No repeated checks for the same node, no walk of already-matched subtrees. **You can expect** a substantial runtime improvement, especially with deeply nested or large queries, plus removal of risk of hitting the recursion limit. * Apply suggestions from code review * Update strawberry/relay/utils.py Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
1 parent eb577c2 commit 023f21a

File tree

1 file changed

+9
-21
lines changed

1 file changed

+9
-21
lines changed

strawberry/relay/utils.py

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from typing_extensions import Self, assert_never
88

99
from strawberry.types.base import StrawberryObjectDefinition
10-
from strawberry.types.nodes import InlineFragment, Selection
10+
from strawberry.types.nodes import InlineFragment
1111

1212
if TYPE_CHECKING:
1313
from strawberry.types.info import Info
@@ -83,31 +83,19 @@ def should_resolve_list_connection_edges(info: Info) -> bool:
8383
8484
"""
8585
resolve_for_field_names = {"edges", "pageInfo"}
86-
87-
def _check_selection(selection: Selection) -> bool:
88-
"""Recursively inspect the selection to check if the user requested to resolve the `edges` field.
89-
90-
Args:
91-
selection (Selection): The selection to check.
92-
93-
Returns:
94-
bool: True if the user requested to resolve the `edges` field of a connection, False otherwise.
95-
"""
86+
# Recursively inspect the selection to check if the user requested to resolve the `edges` field.
87+
stack = []
88+
for selection_field in info.selected_fields:
89+
stack.extend(selection_field.selections)
90+
while stack:
91+
selection = stack.pop()
9692
if (
9793
not isinstance(selection, InlineFragment)
9894
and selection.name in resolve_for_field_names
9995
):
10096
return True
101-
if selection.selections:
102-
return any(
103-
_check_selection(selection) for selection in selection.selections
104-
)
105-
return False
106-
107-
for selection_field in info.selected_fields:
108-
for selection in selection_field.selections:
109-
if _check_selection(selection):
110-
return True
97+
if nested_selections := getattr(selection, "selections", None):
98+
stack.extend(nested_selections)
11199
return False
112100

113101

0 commit comments

Comments
 (0)