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

Speed up cold cache urllib3/boto3/botocore with batched prefetching #2452

Merged
merged 3 commits into from
Apr 8, 2024

Conversation

konstin
Copy link
Member

@konstin konstin commented Mar 14, 2024

With pubgrub being fast for complex ranges, we can now compute the next n candidates without taking a performance hit. This speeds up cold cache urllib3<1.25.4 boto3 from maybe 40s - 50s to ~2s. See docstrings for details on the heuristics.

Before

image

After

image


We need two parts of the prefetching, first looking for compatible version and then falling back to flat next versions. After we selected a boto3 version, there is only one compatible botocore version remaining, so when won't find other compatible candidates for prefetching. We see this as a pattern where we only prefetch boto3 (stack bars), but not botocore (sequential requests between the stacked bars).

image

The risk is that we're completely wrong with the guess and cause a lot of useless network requests. I think this is acceptable since this mechanism only triggers when we're already on the bad path and we should simply have fetched all versions after some seconds (assuming a fast index like pypi).


It would be even better if the pubgrub state was copy-on-write so we could simulate more progress than we actually have; currently we're guessing what the next version is which could be completely wrong, but i think this is still a valuable heuristic.

Fixes #170.

@konstin konstin added the performance Potential performance improvement label Mar 14, 2024
@konstin konstin force-pushed the konsti/fast-boto3 branch 2 times, most recently from 601bcc8 to 775b2a0 Compare March 18, 2024 12:51
@albertferras-vrf
Copy link

thanks for working on this @konstin , looking forward for this massive speed improvement :) . We're currently waiting for uv to be able to resolve boto3 faster before being able to use it

@charliermarsh
Copy link
Member

You might want to consider pinning or bounding boto3 or urllib3, regardless of what you use to resolve / install.

konstin added a commit that referenced this pull request Apr 5, 2024
Batch prefetching needs more information from the candidate selector, so i've split `select` into methods. Split out from #2452. No functional changes.
@konstin konstin force-pushed the konsti/fast-boto3 branch 2 times, most recently from e83f868 to 6c6dbd3 Compare April 5, 2024 14:34
@konstin konstin changed the base branch from main to konsti/refactor-selector April 5, 2024 14:35

// Run the fetcher.
let requests_fut = self.fetch(request_stream).fuse();

// Run the solver.
let resolve_fut = self.solve(request_sink).fuse();
let resolve_fut = self.solve(request_sink).boxed().fuse();
Copy link
Member Author

Choose a reason for hiding this comment

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

Once again making windows happy

@konstin konstin force-pushed the konsti/fast-boto3 branch 2 times, most recently from 4d9ce8a to 116a028 Compare April 5, 2024 14:49
@konstin konstin marked this pull request as ready for review April 5, 2024 14:49
Base automatically changed from konsti/refactor-selector to main April 5, 2024 14:51
konstin added a commit that referenced this pull request Apr 5, 2024
Batch prefetching needs more information from the candidate selector, so
i've split `select` into methods. Split out from #2452. No functional
changes.
compatible,
previous: candidate.version().clone(),
};
candidate
Copy link
Member

Choose a reason for hiding this comment

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

I think we should probably only do this prefetching when the candidate has a wheel. Otherwise, we risk building tons and tons of source distributions.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch

Range::strictly_higher_than(previous)
};
if let Some(candidate) =
selector.select_no_preference(package_name, &range, version_map)
Copy link
Member

Choose a reason for hiding this comment

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

I feel like this risks being quadratic, because we iterate over total_prefetch, and then select_no_preference is also linear, right? Is there any way to improve that?

Copy link
Member Author

Choose a reason for hiding this comment

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

I did an attempt turning select_candidate into an iterator but then looked at the profiles for urllib3/boto3/botocore and i think it's not worth it.

@konstin konstin enabled auto-merge (squash) April 8, 2024 14:19
@konstin konstin changed the title POC: Speed up cold cache boto3/urllib3 with batched prefetching Speed up cold cache urllib3/boto3/botocore with batched prefetching Apr 8, 2024
@konstin konstin disabled auto-merge April 8, 2024 14:27
@konstin konstin enabled auto-merge (squash) April 8, 2024 14:27
@konstin konstin merged commit fb4ba2b into main Apr 8, 2024
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Potential performance improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fetch version metadata in batches
3 participants