Avoid cloning dependency version sets#67
Merged
charliermarsh merged 4 commits intoJun 29, 2026
Conversation
Merging this PR will improve performance by 20.21%
Performance Changes
Tip Curious why this is faster? Use the CodSpeed MCP and ask your agent. Comparing |
charliermarsh
force-pushed
the
charlie/codex-remove-dependency-version-set-clones
branch
from
June 29, 2026 02:33
446afc9 to
8f31b20
Compare
charliermarsh
marked this pull request as ready for review
June 29, 2026 02:34
charliermarsh
added a commit
to astral-sh/uv
that referenced
this pull request
Jun 29, 2026
## Summary This adapts uv to [astral-sh/pubgrub#67](astral-sh/pubgrub#67), where dependency incompatibility kinds store only the dependent and dependency package IDs. The resolver and derivation-chain consumers now recover the version ranges from the incompatibility's ordered terms, including the existing empty-range representation, while the two graph traversals that only need package IDs use the smaller variant directly. The workspace now uses the published `astral-pubgrub` 0.5.0 and `astral-version-ranges` 0.2.0 releases from crates.io. Because those releases include the latest PubGrub changes, this also includes mechanical consumer updates for borrowed `Ranges::iter` bounds and the renamed proxy-package helper.
|
There was previous discussion of this somewhere in our history. I do not have the energy to track it down at the moment. But from recollection we decided to wait until we had significant performance numbers to back up the additional complexity. Which it looks like we have now. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Dependency incompatibilities now store only the dependent and dependency package IDs in
Kind::FromDependencyOf. The corresponding version sets are moved directly into the incompatibility terms instead of being cloned into both representations, and the unchanged four-fieldExternal::FromDependencyOfreport is reconstructed from those terms on the cold error-reporting path.The latest
mainbranch also indexes merge candidates by dependency-range hash. To preserve that behavior without restoring a clone or adding another field to every incompatibility,as_dependencyborrows the optional dependency range from the terms and the merge cache hashes that optional reference. Empty dependencies remain represented by an omitted negative term; self-dependencies, duplicate dependencies, merged dependents, iteration order, and publicIncompatibility::iterbehavior are preserved.This changes the public
Kind::FromDependencyOfvariant from four fields to two, so it is intended for a 0.5.0-or-later release. The dependent uv draft updates the four consumer matches and temporarily pins this commit.Why
Incompatibility::from_dependencyis on the dependency-construction hot path. Previously, it cloned both version sets intoKindeven though the same sets were already owned bypackage_terms. With clone-counting coverage, the constructor now performs zeroVersionSetclones for both empty and non-empty dependencies.The clone-removal mechanism was measured against the independent reserve-only control over five CodSpeed CPU-simulation samples:
sudoku-easysudoku-hardAgainst the original baseline, the cumulative candidate was 26.35% faster on
sudoku-easyand 18.87% faster onsudoku-hard.backtracking_rangesmoved from 1.89 s to 1.90 s, a disclosed 0.53% regression; the other measured benchmarks were neutral to modestly faster. Representative CodSpeed report.The full workspace and focused semantic tests pass, including zero-clone construction, empty and self-dependencies, duplicate term ordering, derivation-tree reconstruction, merged ranges, and package self-dependency behavior. Strict Clippy, formatting, documentation, and diff checks also pass. The small latest-main merge-cache adaptation is integration-only and was not measured separately from the validated clone-removal mechanism.