Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolution speed improvement #3839

Merged
merged 4 commits into from
Jul 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion poetry/puzzle/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,10 @@ def _solve(self, use_latest: List[str] = None) -> Tuple[List[Package], List[int]
except SolveFailure as e:
raise SolverProblemError(e)

# NOTE passing explicit empty array for seen to reset between invocations during update + install cycle
results = dict(
depth_first_search(
PackageNode(self._package, packages), aggregate_package_nodes
PackageNode(self._package, packages, seen=[]), aggregate_package_nodes
)
)

Expand Down Expand Up @@ -373,6 +374,7 @@ def __init__(
self,
package: Package,
packages: List[Package],
seen: List[Package],
previous: Optional["PackageNode"] = None,
previous_dep: Optional[
Union[
Expand All @@ -395,6 +397,7 @@ def __init__(
) -> None:
self.package = package
self.packages = packages
self.seen = seen

self.previous = previous
self.previous_dep = previous_dep
Expand All @@ -417,6 +420,12 @@ def __init__(
def reachable(self) -> List["PackageNode"]:
children: List[PackageNode] = []

# skip already traversed packages
if self.package in self.seen:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an idea: could/should this check be moved to https://github.com/python-poetry/poetry/pull/3839/files#diff-c2fd13b8785fbb20817a8c0e4ce7425249eaa6be7a4faeb1fad846cadccfbfadR363 (part of the depth-first-search method implementation)?

Something along the lines of:

    ...
    for neighbor in node.reachable():
        back_edges[neighbor.id].append(node)
        if neighbor.id in visited:
            continue
        ...

(it feels like the check is an optimization of the DFS algorithm, which is why I wondered if it could live closer to the dfs_visit method rather than being attached to the nodes that the search runs over. I haven't performance evaluated this though, nor checked whether it would behave the same way as your change)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jayaddison quite possibly! I kept the fix as close to the original as possible from August 2020 (before the DFS was more clearly formalized in the code). I expect that the regular authors/maintainers who are more familiar with the internal structure and flow will know where to best plug this fix in. 🙂

return []
else:
self.seen.append(self.package)

if (
self.previous_dep
and self.previous_dep is not self.dep
Expand Down Expand Up @@ -453,6 +462,7 @@ def reachable(self) -> List["PackageNode"]:
PackageNode(
pkg,
self.packages,
self.seen,
self,
dependency,
self.dep or dependency,
Expand Down
10 changes: 5 additions & 5 deletions tests/puzzle/test_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -822,14 +822,14 @@ def test_solver_with_dependency_in_both_main_and_dev_dependencies(
],
)

d = ops[0].package
b = ops[1].package
c = ops[2].package
d = ops[0].package
a = ops[3].package

assert d.category == "dev"
assert c.category == "dev"
assert b.category == "main"
assert c.category == "dev"
assert a.category == "main"


Expand Down Expand Up @@ -881,15 +881,15 @@ def test_solver_with_dependency_in_both_main_and_dev_dependencies_with_one_more_
)

b = ops[0].package
c = ops[3].package
d = ops[1].package
a = ops[2].package
c = ops[3].package
e = ops[4].package

assert d.category == "dev"
assert c.category == "dev"
assert b.category == "main"
assert d.category == "dev"
assert a.category == "main"
assert c.category == "dev"
assert e.category == "main"


Expand Down