Skip to content

Conversation

@codeflash-ai
Copy link

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

📄 13,803% (138.03x) speedup for find_last_node in src/algorithms/graph.py

⏱️ Runtime : 20.4 milliseconds 147 microseconds (best of 250 runs)

📝 Explanation and details

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 22 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Click to see Generated Regression Tests
import pytest  # used for our unit tests
from src.algorithms.graph import find_last_node

# unit tests

# 1. Basic Test Cases


def test_single_node_no_edges():
    # One node, no edges. The node is the last node.
    nodes = [{"id": 1}]
    edges = []
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.25μs -> 1.00μs (25.0% faster)


def test_two_nodes_one_edge():
    # Two nodes, one edge from 1 to 2. Node 2 is the last node.
    nodes = [{"id": 1}, {"id": 2}]
    edges = [{"source": 1, "target": 2}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.71μs -> 1.12μs (51.8% faster)


def test_three_nodes_linear_chain():
    # 1 -> 2 -> 3, so node 3 is the last node.
    nodes = [{"id": 1}, {"id": 2}, {"id": 3}]
    edges = [{"source": 1, "target": 2}, {"source": 2, "target": 3}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 2.12μs -> 1.25μs (70.0% faster)


def test_three_nodes_multiple_sinks():
    # 1 -> 2, 1 -> 3. Both 2 and 3 are last nodes, returns first found (2).
    nodes = [{"id": 1}, {"id": 2}, {"id": 3}]
    edges = [{"source": 1, "target": 2}, {"source": 1, "target": 3}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.83μs -> 1.21μs (51.7% faster)


def test_no_edges_multiple_nodes():
    # Multiple nodes, no edges. All are last nodes, returns first.
    nodes = [{"id": "a"}, {"id": "b"}, {"id": "c"}]
    edges = []
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.17μs -> 1.00μs (16.7% faster)


# 2. Edge Test Cases


def test_empty_nodes_and_edges():
    # No nodes, no edges. Should return None.
    nodes = []
    edges = []
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 708ns -> 875ns (19.1% slower)


def test_edges_but_no_nodes():
    # Edges but no nodes. Should return None.
    nodes = []
    edges = [{"source": 1, "target": 2}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 667ns -> 958ns (30.4% slower)


def test_cycle_graph():
    # Cycle: 1 -> 2 -> 3 -> 1. No last node (all have outgoing edges).
    nodes = [{"id": 1}, {"id": 2}, {"id": 3}]
    edges = [
        {"source": 1, "target": 2},
        {"source": 2, "target": 3},
        {"source": 3, "target": 1},
    ]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 2.17μs -> 1.25μs (73.4% faster)


def test_disconnected_graph():
    # Disconnected: 1 -> 2, 3 (no edges). Last nodes: 2, 3.
    nodes = [{"id": 1}, {"id": 2}, {"id": 3}]
    edges = [{"source": 1, "target": 2}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.79μs -> 1.17μs (53.7% faster)


def test_node_id_types():
    # Node IDs are strings, not ints.
    nodes = [{"id": "start"}, {"id": "end"}]
    edges = [{"source": "start", "target": "end"}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.83μs -> 1.12μs (63.0% faster)


def test_duplicate_nodes():
    # Duplicate nodes with same id, only first is returned.
    nodes = [{"id": 1}, {"id": 1}]
    edges = []
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.25μs -> 1.00μs (25.0% faster)


def test_edge_with_nonexistent_source():
    # Edge references a source not in nodes. Should not affect result.
    nodes = [{"id": 1}]
    edges = [{"source": 999, "target": 1}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.46μs -> 1.08μs (34.6% faster)


def test_edge_with_nonexistent_target():
    # Edge references a target not in nodes. Should not affect result.
    nodes = [{"id": 1}]
    edges = [{"source": 1, "target": 999}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.33μs -> 1.08μs (23.0% faster)


def test_nodes_with_extra_fields():
    # Nodes have extra fields, should still work.
    nodes = [{"id": 1, "name": "A"}, {"id": 2, "name": "B"}]
    edges = [{"source": 1, "target": 2}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.71μs -> 1.12μs (51.8% faster)


def test_edges_with_extra_fields():
    # Edges have extra fields, should still work.
    nodes = [{"id": 1}, {"id": 2}]
    edges = [{"source": 1, "target": 2, "weight": 5}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.71μs -> 1.12μs (51.9% faster)


def test_multiple_last_nodes_returns_first():
    # Multiple last nodes, returns the first in nodes order.
    nodes = [{"id": "x"}, {"id": "y"}, {"id": "z"}]
    edges = [{"source": "x", "target": "y"}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.88μs -> 1.17μs (60.8% faster)


def test_nodes_with_non_hashable_ids():
    # Node id is a tuple.
    nodes = [{"id": (1, 2)}, {"id": (3, 4)}]
    edges = [{"source": (1, 2), "target": (3, 4)}]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.88μs -> 1.21μs (55.2% faster)


# 3. Large Scale Test Cases


def test_large_linear_chain():
    # Large chain: 0 -> 1 -> 2 -> ... -> 999 (last node is 999)
    N = 1000
    nodes = [{"id": i} for i in range(N)]
    edges = [{"source": i, "target": i + 1} for i in range(N - 1)]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 18.2ms -> 55.0μs (33066% faster)


def test_large_star_graph():
    # Star: 0 -> 1, 0 -> 2, ..., 0 -> 999. All except 0 are last nodes.
    N = 1000
    nodes = [{"id": i} for i in range(N)]
    edges = [{"source": 0, "target": i} for i in range(1, N)]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 37.0μs -> 19.9μs (86.4% faster)


def test_large_no_edges():
    # All nodes, no edges. Any node is a last node.
    N = 1000
    nodes = [{"id": i} for i in range(N)]
    edges = []
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 1.25μs -> 1.04μs (20.0% faster)


def test_large_fully_connected():
    # Every node has outgoing edges to all other nodes. No last node.
    N = 50  # (N^2 edges, keep N small for performance)
    nodes = [{"id": i} for i in range(N)]
    edges = [{"source": i, "target": j} for i in range(N) for j in range(N) if i != j]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 2.08ms -> 50.6μs (4009% faster)


def test_large_multiple_disconnected_components():
    # Two chains: 0->1->2 and 100->101->102. Last nodes: 2 and 102.
    nodes = [{"id": 0}, {"id": 1}, {"id": 2}, {"id": 100}, {"id": 101}, {"id": 102}]
    edges = [
        {"source": 0, "target": 1},
        {"source": 1, "target": 2},
        {"source": 100, "target": 101},
        {"source": 101, "target": 102},
    ]
    codeflash_output = find_last_node(nodes, edges)
    result = codeflash_output  # 2.29μs -> 1.33μs (71.9% 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-find_last_node-mjj0io5a and push.

Codeflash Static Badge

@codeflash-ai codeflash-ai bot requested a review from KRRT7 December 23, 2025 20:03
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Dec 23, 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