Skip to content

Avoid cloning dependency version sets#67

Merged
charliermarsh merged 4 commits into
mainfrom
charlie/codex-remove-dependency-version-set-clones
Jun 29, 2026
Merged

Avoid cloning dependency version sets#67
charliermarsh merged 4 commits into
mainfrom
charlie/codex-remove-dependency-version-set-clones

Conversation

@charliermarsh

@charliermarsh charliermarsh commented Jun 29, 2026

Copy link
Copy Markdown
Member

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-field External::FromDependencyOf report is reconstructed from those terms on the cold error-reporting path.

The latest main branch also indexes merge candidates by dependency-range hash. To preserve that behavior without restoring a clone or adding another field to every incompatibility, as_dependency borrows 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 public Incompatibility::iter behavior are preserved.

This changes the public Kind::FromDependencyOf variant 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_dependency is on the dependency-construction hot path. Previously, it cloned both version sets into Kind even though the same sets were already owned by package_terms. With clone-counting coverage, the constructor now performs zero VersionSet clones 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:

Benchmark Reserve-only control Clone removal Change
sudoku-easy 4.70 ms 3.55 ms 24.47% faster
sudoku-hard 4.86 ms 4.17 ms 14.20% faster

Against the original baseline, the cumulative candidate was 26.35% faster on sudoku-easy and 18.87% faster on sudoku-hard. backtracking_ranges moved 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.

@charliermarsh charliermarsh changed the title [codex] Avoid cloning dependency version sets Avoid cloning dependency version sets Jun 29, 2026
@codspeed-hq

codspeed-hq Bot commented Jun 29, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 20.21%

⚡ 2 improved benchmarks
✅ 4 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
sudoku-easy 4.8 ms 4 ms +20.26%
sudoku-hard 5.2 ms 4.4 ms +20.17%

Tip

Curious why this is faster? Use the CodSpeed MCP and ask your agent.


Comparing charlie/codex-remove-dependency-version-set-clones (8fd9709) with main (7c5a0eb)

Open in CodSpeed

@charliermarsh
charliermarsh force-pushed the charlie/codex-remove-dependency-version-set-clones branch from 446afc9 to 8f31b20 Compare June 29, 2026 02:33
@charliermarsh
charliermarsh marked this pull request as ready for review June 29, 2026 02:34
@charliermarsh
charliermarsh merged commit 18b3abb into main Jun 29, 2026
10 checks passed
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.
@Eh2406

Eh2406 commented Jul 1, 2026

Copy link
Copy Markdown

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants