From f7642f2de1b39eecfcf0643b90258bd8cc9feb6a Mon Sep 17 00:00:00 2001 From: Lemonyte <49930425+lemonyte@users.noreply.github.com> Date: Sun, 12 May 2024 15:42:41 -0700 Subject: [PATCH] Improve route finding performance --- src/ferry_planner/route.py | 39 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/ferry_planner/route.py b/src/ferry_planner/route.py index 11bdd68..c7a3c08 100644 --- a/src/ferry_planner/route.py +++ b/src/ferry_planner/route.py @@ -2,7 +2,7 @@ from __future__ import annotations import hashlib -from collections.abc import Iterable, Iterator, Sequence +from collections.abc import Generator, Iterable, Iterator, Sequence from copy import deepcopy from datetime import datetime, timedelta from enum import Enum @@ -182,21 +182,18 @@ def __init__(self, connection_db: ConnectionDB, /) -> None: self._connection_db = connection_db def find_routes(self, *, origin: Location, destination: Location) -> Iterator[Route]: - routes = [] - self._find_routes_recurse(next_point=origin, end_point=destination, routes=routes) - yield from routes + return self._find_routes_recurse(next_point=origin, end_point=destination) def _find_routes_recurse( # noqa: C901, PLR0912, PLR0913 self, *, next_point: Location, end_point: Location, - routes: list[Route], current_route: list[Location] | None = None, dead_ends: list[Connection] | None = None, lands: list[str] | None = None, last_connection_type: type[Connection] = Connection, - ) -> bool: + ) -> Generator[Route, None, bool]: if current_route is None: current_route = [] if dead_ends is None: @@ -205,7 +202,7 @@ def _find_routes_recurse( # noqa: C901, PLR0912, PLR0913 lands = [] current_route.append(next_point) if next_point == end_point: - routes.append(current_route.copy()) + yield current_route.copy() del current_route[-1] return True if isinstance(end_point, City): @@ -216,7 +213,7 @@ def _find_routes_recurse( # noqa: C901, PLR0912, PLR0913 pass else: current_route.append(end_point) - routes.append(current_route.copy()) + yield current_route.copy() del current_route[-2:] return True res = False @@ -235,18 +232,20 @@ def _find_routes_recurse( # noqa: C901, PLR0912, PLR0913 lands.append(connection.origin.land_group) else: lands.append("") - if self._find_routes_recurse( - next_point=connection.destination, - end_point=end_point, - routes=routes, - current_route=current_route, - dead_ends=dead_ends, - lands=lands, - last_connection_type=type(connection), - ): - res = True - else: - dead_ends.append(connection) + try: + yield from self._find_routes_recurse( + next_point=connection.destination, + end_point=end_point, + current_route=current_route, + dead_ends=dead_ends, + lands=lands, + last_connection_type=type(connection), + ) + except StopIteration as exc: + if exc.value is True: + res = True + else: + dead_ends.append(connection) del lands[-1] del current_route[-1] return res