Skip to content

Select resolver prefetch candidates in one pass - #20487

Closed
charliermarsh wants to merge 1 commit into
mainfrom
charlie/codex-prefetch-candidates-in-one-pass
Closed

Select resolver prefetch candidates in one pass#20487
charliermarsh wants to merge 1 commit into
mainfrom
charlie/codex-prefetch-candidates-in-one-pass

Conversation

@charliermarsh

Copy link
Copy Markdown
Member

Summary

Batch prefetch currently selects up to 50 candidates by repeatedly invoking the full candidate selector and intersecting a singleton complement into the remaining range. On backtracking-heavy packages, those repeated traversals and increasingly fragmented ranges add meaningful resolver CPU before the metadata requests are even issued.

This adds a batched selector that visits each version map once, preserves highest/lowest ordering, prerelease and cutoff handling, index strategy and duplicate-index precedence, compatible/incompatible candidates, and the compatible-to-in-order phase transition, then enqueues the same eligible wheel metadata requests. This is distinct from #20465: it does not suppress later prefetch opportunities; it only makes selection within each batch linear.

This is deliberately a draft because collecting a batch before enqueueing its first request can trade away some cold-network overlap. The target benchmark is warm/offline.

Performance

Measured directly against latest main (bedddb53a) with profiling binaries and a prewarmed PyPI cache. All runs were offline uv pip compile, Python 3.12, fixed UV_EXCLUDE_NEWER=2024-08-08T00:00:00Z, UV_CONCURRENT_CACHE_READS=4, CPUs 8-15, 20 warmups, and 80 alternating pairs. Every generated requirements file matched byte-for-byte.

workload wall before → after wall change (95% CI) CPU before → after CPU change (95% CI)
jupyter (97 packages) 97.6 → 98.5 ms +4.8% [-0.3, +10.2] 54.6 → 54.5 ms +0.3% [-0.6, +1.2]
boto3 (7 packages, backtracking) 163.3 → 157.3 ms -3.6% [-6.6, -0.5] 229.2 → 218.8 ms -6.6% [-9.1, -4.1]
airflow (559 packages) 243.4 → 241.8 ms -0.2% [-2.0, +1.5] 370.6 → 369.3 ms -0.7% [-1.7, +0.2]
large-index (26 large Simple pages, no deps) 102.6 → 103.0 ms +1.4% [-3.6, +6.3] 58.5 → 58.3 ms -0.3% [-1.1, +0.5]

boto3 is the meaningful win, which matches its roughly 94 large prefetch batches. A focused selector-equivalence matrix covers highest/lowest, all three index strategies, prerelease modes, duplicate versions, compatible/incompatible/cutoff entries, and segmented ranges; it also matched 300,000 randomized cases against repeated selection. The full resolver unit suite (65 tests), strict clippy including tests, formatting, and diff checks pass.

@astral-sh-bot

astral-sh-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

uv test inventory changes

This PR changes the tests when compared with the main base revision.

  • Added tests: 1
  • Removed tests: 0
  • Changed suites: 1
uv-resolver: +1 / -0

Added:

  • uv-resolver::candidate_selector::tests::batched_selector_matches_repeated_selection

Removed: none

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants