cover/benches/bench_library.rs

79 lines
2.1 KiB
Rust

use criterion::{criterion_group, criterion_main, Criterion};
use rand::{
distributions::{Alphanumeric, DistString},
thread_rng, Rng,
};
use cover::library::{Artist, Library, Song};
// actual benchmarks
fn bench_random_library(c: &mut Criterion) {
bench_random_library_with_sizes(c, "small", 5, 25);
bench_random_library_with_sizes(c, "medium", 25, 100);
bench_random_library_with_sizes(c, "large", 100, 1000);
bench_random_library_with_sizes(c, "massive", 1000, 2500);
}
fn bench_supermassive_random_library(c: &mut Criterion) {
bench_random_library_with_sizes(c, "supermassive", 2500, 7500);
}
// benchmark helpers
fn bench_random_library_with_sizes(c: &mut Criterion, size: &str, artists: usize, songs: usize) {
let id = format!("{size} random library ({artists} artists x {songs} songs/artist)");
let library = random_library(artists, songs);
c.bench_function(id.as_str(), |b| {
b.iter(|| {
library.library_covers();
})
});
}
// test data generators
fn random_string() -> String {
let mut rng = thread_rng();
let length = rng.gen_range(1..=20);
Alphanumeric.sample_string(&mut rng, length)
}
fn generate_iter<T: Clone>(generator: impl Fn() -> T, length: usize) -> impl Iterator<Item = T> {
let mut ts = Vec::with_capacity(length);
for _ in 0..length {
ts.push(generator())
}
ts.into_iter()
}
fn random_song() -> Song {
Song::new(
random_string(),
random_string(),
generate_iter(random_string, 5),
)
}
fn random_artist(songs: usize) -> Artist {
Artist::new(
random_string(),
generate_iter(random_string, 5),
generate_iter(random_song, songs),
)
}
fn random_library(artists: usize, songs_per_artist: usize) -> Library {
Library::new(generate_iter(|| random_artist(songs_per_artist), artists))
}
// entrypoint
criterion_group!(benches, bench_random_library);
criterion_group! {
name = slow_benches;
config = Criterion::default().sample_size(20);
targets = bench_supermassive_random_library
}
criterion_main!(benches, slow_benches);