Skip to content

Commit 69a4d71

Browse files
⚡️ Speed up method PathFinder.find_shortest_path by 246%
The optimized code achieves a 245% speedup through two key algorithmic improvements: **1. Replaced list-based queue with deque for O(1) operations** The original code used `queue.pop(0)` on a list, which is O(n) because it shifts all remaining elements. The line profiler shows this operation taking 15.4% of total time (2.327ms out of 15.129ms). The optimized version uses `collections.deque` with `popleft()`, which is O(1). This change alone eliminates the most expensive operation in the BFS traversal. **2. Eliminated path copying with parent tracking** The original code maintained complete paths by copying and extending them (`new_path = list(path)` + `new_path.append(neighbor)`), taking 19.7% of total time (12.6% + 7.1%). With thousands of nodes visited, this creates substantial memory allocation overhead. The optimized version stores only parent pointers in a dictionary and reconstructs the path once at the end, reducing both time and space complexity. **Performance characteristics by test case type:** - **Large linear graphs (1000+ nodes)**: Show the most dramatic improvement (400-433% faster) because they maximize the impact of both optimizations - many queue operations and long paths to copy - **Small graphs (2-5 nodes)**: Actually perform 17-50% slower due to the overhead of importing deque and managing the parent dictionary, but the absolute difference is negligible (microseconds) - **Dense/branching graphs**: Show moderate improvements (10-96% faster) as they benefit from reduced queue overhead but have shorter average path lengths - **Disconnected graphs**: Benefit significantly (286% faster) when no path exists, as the BFS explores many nodes before terminating The optimization transforms the algorithm from O(V²) time complexity (due to path copying) to O(V + E), making it scale much better for larger graphs while maintaining identical BFS shortest-path semantics.
1 parent 9b951ff commit 69a4d71

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

src/dsa/various.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import re
2+
from collections import deque
23

34

45
class Graph:
@@ -96,21 +97,25 @@ def find_shortest_path(self, start: str, end: str) -> list[str]:
9697
if start not in self.graph or end not in self.graph:
9798
return []
9899

99-
queue = [[start]]
100+
queue = deque([start])
100101
visited = set([start])
102+
parent = {start: None}
101103

102104
while queue:
103-
path = queue.pop(0)
104-
node = path[-1]
105+
node = queue.popleft()
105106

106107
if node == end:
107-
return path
108+
# Reconstruct path backwards
109+
path = []
110+
while node is not None:
111+
path.append(node)
112+
node = parent[node]
113+
return path[::-1]
108114

109115
for neighbor in self.graph.get(node, []):
110116
if neighbor not in visited:
111117
visited.add(neighbor)
112-
new_path = list(path)
113-
new_path.append(neighbor)
114-
queue.append(new_path)
118+
parent[neighbor] = node
119+
queue.append(neighbor)
115120

116121
return [] # No path found

0 commit comments

Comments
 (0)