mirror of https://github.com/astral-sh/uv
Add basic universal benchmarks to CI (#5938)
## Summary Resolves https://github.com/astral-sh/uv/issues/4921.
This commit is contained in:
parent
7fdb878fd0
commit
ddb82a01c8
|
|
@ -1494,7 +1494,8 @@ jobs:
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y libsasl2-dev libldap2-dev libkrb5-dev
|
sudo apt-get install -y libsasl2-dev libldap2-dev libkrb5-dev
|
||||||
cargo run --bin uv -- venv --cache-dir .cache
|
cargo run --bin uv -- venv --cache-dir .cache
|
||||||
cargo run --bin uv -- pip compile scripts/requirements/airflow.in --exclude-newer 2024-06-20 --cache-dir .cache
|
cargo run --bin uv -- pip compile scripts/requirements/jupyter.in --universal --exclude-newer 2024-08-08 --cache-dir .cache
|
||||||
|
cargo run --bin uv -- pip compile scripts/requirements/airflow.in --universal --exclude-newer 2024-08-08 --cache-dir .cache
|
||||||
|
|
||||||
- name: "Build benchmarks"
|
- name: "Build benchmarks"
|
||||||
run: cargo codspeed build --features codspeed -p bench
|
run: cargo codspeed build --features codspeed -p bench
|
||||||
|
|
|
||||||
|
|
@ -393,6 +393,7 @@ dependencies = [
|
||||||
"distribution-filename",
|
"distribution-filename",
|
||||||
"distribution-types",
|
"distribution-types",
|
||||||
"install-wheel-rs",
|
"install-wheel-rs",
|
||||||
|
"pep440_rs",
|
||||||
"pep508_rs",
|
"pep508_rs",
|
||||||
"platform-tags",
|
"platform-tags",
|
||||||
"pypi-types",
|
"pypi-types",
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ harness = false
|
||||||
distribution-filename = { workspace = true }
|
distribution-filename = { workspace = true }
|
||||||
distribution-types = { workspace = true }
|
distribution-types = { workspace = true }
|
||||||
install-wheel-rs = { workspace = true }
|
install-wheel-rs = { workspace = true }
|
||||||
|
pep440_rs = { workspace = true }
|
||||||
pep508_rs = { workspace = true }
|
pep508_rs = { workspace = true }
|
||||||
platform-tags = { workspace = true }
|
platform-tags = { workspace = true }
|
||||||
pypi-types = { workspace = true }
|
pypi-types = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -9,67 +9,75 @@ use uv_python::PythonEnvironment;
|
||||||
use uv_resolver::Manifest;
|
use uv_resolver::Manifest;
|
||||||
|
|
||||||
fn resolve_warm_jupyter(c: &mut Criterion<WallTime>) {
|
fn resolve_warm_jupyter(c: &mut Criterion<WallTime>) {
|
||||||
let runtime = &tokio::runtime::Builder::new_current_thread()
|
let run = setup(Manifest::simple(vec![Requirement::from(
|
||||||
.enable_all()
|
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let cache = &Cache::from_path("../../.cache").init().unwrap();
|
|
||||||
let venv = PythonEnvironment::from_root("../../.venv", cache).unwrap();
|
|
||||||
let client = &RegistryClientBuilder::new(cache.clone()).build();
|
|
||||||
let manifest = &Manifest::simple(vec![Requirement::from(
|
|
||||||
pep508_rs::Requirement::from_str("jupyter==1.0.0").unwrap(),
|
pep508_rs::Requirement::from_str("jupyter==1.0.0").unwrap(),
|
||||||
)]);
|
)]));
|
||||||
|
c.bench_function("resolve_warm_jupyter", |b| b.iter(|| run(false)));
|
||||||
|
}
|
||||||
|
|
||||||
let run = || {
|
fn resolve_warm_jupyter_universal(c: &mut Criterion<WallTime>) {
|
||||||
runtime
|
let run = setup(Manifest::simple(vec![Requirement::from(
|
||||||
.block_on(resolver::resolve(
|
pep508_rs::Requirement::from_str("jupyter==1.0.0").unwrap(),
|
||||||
black_box(manifest.clone()),
|
)]));
|
||||||
black_box(cache.clone()),
|
c.bench_function("resolve_warm_jupyter_universal", |b| b.iter(|| run(true)));
|
||||||
black_box(client),
|
|
||||||
&venv,
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
};
|
|
||||||
|
|
||||||
c.bench_function("resolve_warm_jupyter", |b| b.iter(run));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_warm_airflow(c: &mut Criterion<WallTime>) {
|
fn resolve_warm_airflow(c: &mut Criterion<WallTime>) {
|
||||||
let runtime = &tokio::runtime::Builder::new_current_thread()
|
let run = setup(Manifest::simple(vec![
|
||||||
|
Requirement::from(pep508_rs::Requirement::from_str("apache-airflow[all]==2.9.3").unwrap()),
|
||||||
|
Requirement::from(
|
||||||
|
pep508_rs::Requirement::from_str("apache-airflow-providers-apache-beam>3.0.0").unwrap(),
|
||||||
|
),
|
||||||
|
]));
|
||||||
|
c.bench_function("resolve_warm_airflow", |b| b.iter(|| run(false)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This takes >5m to run in CodSpeed.
|
||||||
|
// fn resolve_warm_airflow_universal(c: &mut Criterion<WallTime>) {
|
||||||
|
// let run = setup(Manifest::simple(vec![
|
||||||
|
// Requirement::from(pep508_rs::Requirement::from_str("apache-airflow[all]").unwrap()),
|
||||||
|
// Requirement::from(
|
||||||
|
// pep508_rs::Requirement::from_str("apache-airflow-providers-apache-beam>3.0.0").unwrap(),
|
||||||
|
// ),
|
||||||
|
// ]));
|
||||||
|
// c.bench_function("resolve_warm_airflow_universal", |b| b.iter(|| run(true)));
|
||||||
|
// }
|
||||||
|
|
||||||
|
criterion_group!(
|
||||||
|
uv,
|
||||||
|
resolve_warm_jupyter,
|
||||||
|
resolve_warm_jupyter_universal,
|
||||||
|
resolve_warm_airflow
|
||||||
|
);
|
||||||
|
criterion_main!(uv);
|
||||||
|
|
||||||
|
fn setup(manifest: Manifest) -> impl Fn(bool) {
|
||||||
|
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||||
// CodSpeed limits the total number of threads to 500
|
// CodSpeed limits the total number of threads to 500
|
||||||
.max_blocking_threads(256)
|
.max_blocking_threads(256)
|
||||||
.enable_all()
|
.enable_all()
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let cache = &Cache::from_path("../../.cache").init().unwrap();
|
let cache = Cache::from_path("../../.cache").init().unwrap();
|
||||||
let venv = PythonEnvironment::from_root("../../.venv", cache).unwrap();
|
let interpreter = PythonEnvironment::from_root("../../.venv", &cache)
|
||||||
let client = &RegistryClientBuilder::new(cache.clone()).build();
|
.unwrap()
|
||||||
let manifest = &Manifest::simple(vec![
|
.into_interpreter();
|
||||||
Requirement::from(pep508_rs::Requirement::from_str("apache-airflow[all]==2.9.2").unwrap()),
|
let client = RegistryClientBuilder::new(cache.clone()).build();
|
||||||
Requirement::from(
|
|
||||||
pep508_rs::Requirement::from_str("apache-airflow-providers-apache-beam>3.0.0").unwrap(),
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
let run = || {
|
move |universal| {
|
||||||
runtime
|
runtime
|
||||||
.block_on(resolver::resolve(
|
.block_on(resolver::resolve(
|
||||||
black_box(manifest.clone()),
|
black_box(manifest.clone()),
|
||||||
black_box(cache.clone()),
|
black_box(cache.clone()),
|
||||||
black_box(client),
|
black_box(&client),
|
||||||
&venv,
|
&interpreter,
|
||||||
|
universal,
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
};
|
}
|
||||||
|
|
||||||
c.bench_function("resolve_warm_airflow", |b| b.iter(run));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
criterion_group!(uv, resolve_warm_airflow, resolve_warm_jupyter);
|
|
||||||
criterion_main!(uv);
|
|
||||||
|
|
||||||
mod resolver {
|
mod resolver {
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
|
|
@ -78,6 +86,7 @@ mod resolver {
|
||||||
|
|
||||||
use distribution_types::IndexLocations;
|
use distribution_types::IndexLocations;
|
||||||
use install_wheel_rs::linker::LinkMode;
|
use install_wheel_rs::linker::LinkMode;
|
||||||
|
use pep440_rs::Version;
|
||||||
use pep508_rs::{MarkerEnvironment, MarkerEnvironmentBuilder};
|
use pep508_rs::{MarkerEnvironment, MarkerEnvironmentBuilder};
|
||||||
use platform_tags::{Arch, Os, Platform, Tags};
|
use platform_tags::{Arch, Os, Platform, Tags};
|
||||||
use uv_cache::Cache;
|
use uv_cache::Cache;
|
||||||
|
|
@ -89,10 +98,10 @@ mod resolver {
|
||||||
use uv_dispatch::BuildDispatch;
|
use uv_dispatch::BuildDispatch;
|
||||||
use uv_distribution::DistributionDatabase;
|
use uv_distribution::DistributionDatabase;
|
||||||
use uv_git::GitResolver;
|
use uv_git::GitResolver;
|
||||||
use uv_python::PythonEnvironment;
|
use uv_python::Interpreter;
|
||||||
use uv_resolver::{
|
use uv_resolver::{
|
||||||
FlatIndex, InMemoryIndex, Manifest, OptionsBuilder, PythonRequirement, ResolutionGraph,
|
FlatIndex, InMemoryIndex, Manifest, OptionsBuilder, PythonRequirement, RequiresPython,
|
||||||
Resolver, ResolverMarkers,
|
ResolutionGraph, Resolver, ResolverMarkers,
|
||||||
};
|
};
|
||||||
use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight};
|
use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight};
|
||||||
|
|
||||||
|
|
@ -127,14 +136,15 @@ mod resolver {
|
||||||
manifest: Manifest,
|
manifest: Manifest,
|
||||||
cache: Cache,
|
cache: Cache,
|
||||||
client: &RegistryClient,
|
client: &RegistryClient,
|
||||||
venv: &PythonEnvironment,
|
interpreter: &Interpreter,
|
||||||
|
universal: bool,
|
||||||
) -> Result<ResolutionGraph> {
|
) -> Result<ResolutionGraph> {
|
||||||
let build_isolation = BuildIsolation::Isolated;
|
let build_isolation = BuildIsolation::Isolated;
|
||||||
let build_options = BuildOptions::default();
|
let build_options = BuildOptions::default();
|
||||||
let concurrency = Concurrency::default();
|
let concurrency = Concurrency::default();
|
||||||
let config_settings = ConfigSettings::default();
|
let config_settings = ConfigSettings::default();
|
||||||
let exclude_newer = Some(
|
let exclude_newer = Some(
|
||||||
NaiveDate::from_ymd_opt(2024, 6, 20)
|
NaiveDate::from_ymd_opt(2024, 8, 8)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.and_hms_opt(0, 0, 0)
|
.and_hms_opt(0, 0, 0)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -148,13 +158,19 @@ mod resolver {
|
||||||
let index = InMemoryIndex::default();
|
let index = InMemoryIndex::default();
|
||||||
let index_locations = IndexLocations::default();
|
let index_locations = IndexLocations::default();
|
||||||
let installed_packages = EmptyInstalledPackages;
|
let installed_packages = EmptyInstalledPackages;
|
||||||
let interpreter = venv.interpreter();
|
|
||||||
let python_requirement = PythonRequirement::from_interpreter(interpreter);
|
|
||||||
let sources = SourceStrategy::default();
|
let sources = SourceStrategy::default();
|
||||||
|
|
||||||
let options = OptionsBuilder::new().exclude_newer(exclude_newer).build();
|
let options = OptionsBuilder::new().exclude_newer(exclude_newer).build();
|
||||||
let build_constraints = [];
|
let build_constraints = [];
|
||||||
|
|
||||||
|
let python_requirement = if universal {
|
||||||
|
PythonRequirement::from_requires_python(
|
||||||
|
interpreter,
|
||||||
|
&RequiresPython::greater_than_equal_version(&Version::new([3, 11])),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
PythonRequirement::from_interpreter(interpreter)
|
||||||
|
};
|
||||||
|
|
||||||
let build_context = BuildDispatch::new(
|
let build_context = BuildDispatch::new(
|
||||||
client,
|
client,
|
||||||
&cache,
|
&cache,
|
||||||
|
|
@ -177,11 +193,17 @@ mod resolver {
|
||||||
PreviewMode::Disabled,
|
PreviewMode::Disabled,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let markers = if universal {
|
||||||
|
ResolverMarkers::universal(None)
|
||||||
|
} else {
|
||||||
|
ResolverMarkers::specific_environment(MARKERS.clone())
|
||||||
|
};
|
||||||
|
|
||||||
let resolver = Resolver::new(
|
let resolver = Resolver::new(
|
||||||
manifest,
|
manifest,
|
||||||
options,
|
options,
|
||||||
&python_requirement,
|
&python_requirement,
|
||||||
ResolverMarkers::SpecificEnvironment(MARKERS.clone()),
|
markers,
|
||||||
Some(&TAGS),
|
Some(&TAGS),
|
||||||
&flat_index,
|
&flat_index,
|
||||||
&index,
|
&index,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue