From d849a4218b1fda43e981e4fbe1f3b859822b08a3 Mon Sep 17 00:00:00 2001 From: "codeflash-ai[bot]" <148906541+codeflash-ai[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 05:34:54 +0000 Subject: [PATCH] Optimize find_last_node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The optimized code achieves a **222x speedup** by eliminating a nested loop anti-pattern that created O(n*m) time complexity. **What changed:** The original implementation used a nested comprehension `all(e["source"] != n["id"] for e in edges)` that, for each node, iterated through ALL edges to verify none had that node as a source. This means for every node candidate, the entire edge list was scanned. The optimization **pre-computes a set** of all source IDs once (`source_ids = {e["source"] for e in edges}`), then performs a simple O(1) set membership check (`n["id"] not in source_ids`) for each node. **Why it's faster:** - **Original**: O(n × m) - For n nodes and m edges, this performs up to n×m comparisons - **Optimized**: O(n + m) - Creates the set in O(m) time, then checks n nodes in O(1) each The performance gain is most dramatic when both node and edge counts are large, as shown in the tests: - `test_large_linear_chain`: **31,815% faster** (17.8ms → 55.8μs) with 1000 nodes/999 edges - `test_large_graph_no_last_node`: **32,219% faster** (17.7ms → 54.8μs) - `test_large_complete_binary_tree`: **12,333% faster** (2.26ms → 18.2μs) Even small graphs benefit significantly (50-90% faster in most test cases) because set construction and membership testing are highly optimized in Python's C implementation. **Impact:** This optimization is crucial if `find_last_node` is called frequently or on graphs with hundreds/thousands of nodes and edges. The quadratic behavior of the original would become a bottleneck in any workflow processing multiple large graphs. The optimized version scales linearly and maintains consistent sub-millisecond performance even on 1000-node graphs. --- src/algorithms/graph.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/algorithms/graph.py b/src/algorithms/graph.py index 777ea3b..156485a 100644 --- a/src/algorithms/graph.py +++ b/src/algorithms/graph.py @@ -47,7 +47,8 @@ def find_shortest_path(self, start: str, end: str) -> list[str]: def find_last_node(nodes, edges): """This function receives a flow and returns the last node.""" - return next((n for n in nodes if all(e["source"] != n["id"] for e in edges)), None) + source_ids = {e["source"] for e in edges} + return next((n for n in nodes if n["id"] not in source_ids), None) def find_leaf_nodes(nodes: list[dict], edges: list[dict]) -> list[dict]: