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

Add bench for backtracking #281

Merged
merged 1 commit into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ include = ["Cargo.toml", "LICENSE", "README.md", "src/**", "tests/**", "examples

[dependencies]
indexmap = "2.6.0"
log = "0.4.22" # for debug logs in tests
# for debug logs in tests
log = "0.4.22"
priority-queue = "2.1.1"
rustc-hash = ">=1.0.0, <3.0.0"
serde = { version = "1.0", features = ["derive"], optional = true }
Expand All @@ -42,6 +43,10 @@ version-ranges = { version = "0.1.0", path = "version-ranges", features = ["prop
[features]
serde = ["dep:serde", "version-ranges/serde"]

[[bench]]
name = "backtracking"
harness = false

[[bench]]
name = "large_case"
harness = false
Expand Down
98 changes: 98 additions & 0 deletions benches/backtracking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// SPDX-License-Identifier: MPL-2.0

//! This bench monitors the performance of backtracking and term intersection.
//!
//! Dependencies are constructed in a way that all versions need to be tested before finding a solution.

use criterion::*;
use pubgrub::OfflineDependencyProvider;
use version_ranges::Ranges;

/// This benchmark is a simplified reproduction of one of the patterns found in the `solana-*` crates from Cargo:
/// * `solana-archiver-lib v1.1.12` depends on many layers of other solana crates with req `>= 1.1.12`.
/// * each version `1.x.y` higher than `1.5.15` of a solana crate depends on other solana crates with req `= 1.x.y`.
/// * `solana-crate-features` depends on `cc` with the `num_cpus` feature, which doesn't exist in recent versions of `cc`.
fn backtracking_singletons(c: &mut Criterion, package_count: u32, version_count: u32) {
let mut dependency_provider = OfflineDependencyProvider::<u32, Ranges<u32>>::new();

dependency_provider.add_dependencies(0u32, 0u32, [(1u32, Ranges::full())]);
dependency_provider.add_dependencies(1u32, 0u32, []);

for n in 1..package_count {
for v in 1..version_count {
dependency_provider.add_dependencies(n, v, [(n + 1, Ranges::singleton(v))]);
}
}

c.bench_function("backtracking_singletons", |b| {
b.iter(|| {
let _ = pubgrub::resolve(&dependency_provider, 0u32, 0u32);
})
});
}

/// This benchmark is a simplified reproduction of one of the patterns found in the `solana-*` crates from Cargo:
/// * `solana-archiver-lib v1.1.12` depends on many layers of other solana crates with req `>= 1.1.12`.
/// * `solana-archiver-lib v1.1.12` also depends on `ed25519-dalek v1.0.0-pre.3`.
/// * each version `1.x.y` higher than `1.5.15` of a solana crate depends on other solana crates with req `= 1.x.y`.
/// * `solana-crate-features >= 1.2.17` depends on `ed25519-dalek v1.0.0-pre.4` or a higher incompatible version.
fn backtracking_disjoint_versions(c: &mut Criterion, package_count: u32, version_count: u32) {
let mut dependency_provider = OfflineDependencyProvider::<u32, Ranges<u32>>::new();

let root_deps = [(1u32, Ranges::full()), (u32::MAX, Ranges::singleton(0u32))];
dependency_provider.add_dependencies(0u32, 0u32, root_deps);

dependency_provider.add_dependencies(1u32, 0u32, []);

for n in 1..package_count {
for v in 1..version_count {
dependency_provider.add_dependencies(n, v, [(n + 1, Ranges::singleton(v))]);
}
}
for v in 1..version_count {
dependency_provider.add_dependencies(package_count, v, [(u32::MAX, Ranges::singleton(v))]);
}

for v in 0..version_count {
dependency_provider.add_dependencies(u32::MAX, v, []);
}

c.bench_function("backtracking_disjoint_versions", |b| {
b.iter(|| {
let _ = pubgrub::resolve(&dependency_provider, 0u32, 0u32);
})
});
}

/// This benchmark is a simplified reproduction of one of the patterns found in the `solana-*` crates from Cargo:
/// * `solana-archiver-lib v1.1.12` depends on many layers of other solana crates with req `>= 1.1.12`.
/// * each version `1.x.y` lower than `1.5.14` of a solana crate depends on other solana crates with req `>= 1.x.y`.
/// * `solana-crate-features` depends on `cc` with the `num_cpus` feature, which doesn't exist in recent versions of `cc`.
fn backtracking_ranges(c: &mut Criterion, package_count: u32, version_count: u32) {
let mut dependency_provider = OfflineDependencyProvider::<u32, Ranges<u32>>::new();

dependency_provider.add_dependencies(0u32, 0u32, [(1u32, Ranges::full())]);
dependency_provider.add_dependencies(1u32, 0u32, []);

for n in 1..package_count {
for v in 1..version_count {
let r = Ranges::higher_than(version_count - v);
dependency_provider.add_dependencies(n, v, [(n + 1, r)]);
}
}

c.bench_function("backtracking_ranges", |b| {
b.iter(|| {
let _ = pubgrub::resolve(&dependency_provider, 0u32, 0u32);
})
});
}

fn bench_group(c: &mut Criterion) {
backtracking_singletons(c, 100, 500);
backtracking_disjoint_versions(c, 300, 200);
backtracking_ranges(c, 5, 200);
}

criterion_group!(benches, bench_group);
criterion_main!(benches);
1 change: 1 addition & 0 deletions benches/large_case.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: MPL-2.0

use std::time::Duration;

use criterion::*;
Expand Down
4 changes: 2 additions & 2 deletions benches/sudoku.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ fn from_board(b: &str) -> Vec<(SudokuPackage, Range<Arc<usize>>)> {
if let Some(val) = val.chars().next().unwrap().to_digit(10) {
out.push((
SudokuPackage::Cell {
row: (row + 1).try_into().unwrap(),
col: (col + 1).try_into().unwrap(),
row: row + 1,
col: col + 1,
},
Range::singleton(val as usize),
));
Expand Down
2 changes: 1 addition & 1 deletion test-examples/large_case_u16_NumberVersion.ron
Original file line number Diff line number Diff line change
Expand Up @@ -5521,4 +5521,4 @@
18: {},
19: {},
},
}
}