From 8c30c13e80c1c5cfcaf276d6aca5fcb3945c9bc5 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sat, 27 Apr 2024 21:04:22 +0200 Subject: [PATCH] Add benchmarks for k_smallest implementation variants. --- Cargo.toml | 6 ++++- benches/k_smallest.rs | 61 +++++++++++++++++++++++++++++++++++++++++++ src/k_smallest.rs | 1 + 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 benches/k_smallest.rs diff --git a/Cargo.toml b/Cargo.toml index 7fb6a3980..4ee209c4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ either = { version = "1.0", default-features = false } [dev-dependencies] rand = "0.7" -criterion = "0.4.0" +criterion = { version = "0.4.0", features = ["html_reports"] } paste = "1.0.0" # Used in test_std to instantiate generic tests permutohedron = "0.2" quickcheck = { version = "0.9", default_features = false } @@ -75,3 +75,7 @@ harness = false [[bench]] name = "specializations" harness = false + +[[bench]] +name = "k_smallest" +harness = false diff --git a/benches/k_smallest.rs b/benches/k_smallest.rs new file mode 100644 index 000000000..509ed7f8a --- /dev/null +++ b/benches/k_smallest.rs @@ -0,0 +1,61 @@ +use criterion::{black_box, criterion_group, criterion_main, Bencher, BenchmarkId, Criterion}; +use itertools::Itertools; +use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng}; + +fn strict(b: &mut Bencher, (k, vals): &(usize, &Vec)) { + b.iter(|| black_box(vals.iter()).k_smallest(*k)) +} + +fn relaxed(b: &mut Bencher, (k, vals): &(usize, &Vec)) { + b.iter(|| black_box(vals.iter()).k_smallest_relaxed(*k)) +} + +fn ascending(n: usize) -> Vec { + (0..n).collect() +} + +fn random(n: usize) -> Vec { + let mut vals = (0..n).collect_vec(); + vals.shuffle(&mut StdRng::seed_from_u64(42)); + vals +} + +fn descending(n: usize) -> Vec { + (0..n).rev().collect() +} + +fn k_smallest(c: &mut Criterion, order: &str, vals: fn(usize) -> Vec) { + let mut g = c.benchmark_group(format!("k-smallest/{order}")); + + for log_n in 20..23 { + let n = 1 << log_n; + + let vals = vals(n); + + for log_k in 7..10 { + let k = 1 << log_k; + + let params = format!("{log_n}/{log_k}"); + let input = (k, &vals); + g.bench_with_input(BenchmarkId::new("strict", ¶ms), &input, strict); + g.bench_with_input(BenchmarkId::new("relaxed", ¶ms), &input, relaxed); + } + } + + g.finish() +} + +fn k_smallest_asc(c: &mut Criterion) { + k_smallest(c, "asc", ascending); +} + +fn k_smallest_rand(c: &mut Criterion) { + k_smallest(c, "rand", random); +} + +fn k_smallest_desc(c: &mut Criterion) { + k_smallest(c, "desc", descending); +} + +criterion_group!(benches, k_smallest_asc, k_smallest_rand, k_smallest_desc); +criterion_main!(benches); diff --git a/src/k_smallest.rs b/src/k_smallest.rs index 083c1b00d..7e4ace262 100644 --- a/src/k_smallest.rs +++ b/src/k_smallest.rs @@ -114,6 +114,7 @@ where return; } + assert_ne!(buf.len(), buf.capacity()); buf.push(val); if buf.len() == 2 * k {