diff --git a/Cargo.toml b/Cargo.toml index e9db335..d3815b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,10 @@ rustversion = "1.0" test-log = { version ="0.2.11", features = ["trace"] } trybuild = "1.0" +[[bench]] +name = "compare" +harness = false + [[bench]] name = "incremental" diff --git a/benches/compare.rs b/benches/compare.rs new file mode 100644 index 0000000..ac15ac9 --- /dev/null +++ b/benches/compare.rs @@ -0,0 +1,93 @@ +use codspeed_criterion_compat::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use salsa::Setter; + +#[salsa::input] +pub struct Input { + pub text: String, +} + +#[salsa::tracked] +pub fn length(db: &dyn salsa::Database, input: Input) -> usize { + input.text(db).len() +} + +#[salsa::interned] +pub struct InternedInput<'db> { + pub text: String, +} + +#[salsa::tracked] +pub fn interned_length<'db>(db: &'db dyn salsa::Database, input: InternedInput<'db>) -> usize { + input.text(db).len() +} + +fn mutating_inputs(c: &mut Criterion) { + let mut group: codspeed_criterion_compat::BenchmarkGroup< + codspeed_criterion_compat::measurement::WallTime, + > = c.benchmark_group("Mutating Inputs"); + + let mut db = salsa::DatabaseImpl::default(); + + for n in &[10, 20, 30] { + let base_string = "hello, world!".to_owned(); + let base_len = base_string.len(); + + let string = base_string.clone().repeat(*n); + let new_len = string.len(); + + group.bench_function(BenchmarkId::new("mutating", n), |b| { + b.iter(|| { + let input = Input::new(&db, base_string.clone()); + let actual_len = length(&db, input); + assert_eq!(base_len, actual_len); + + input.set_text(&mut db).to(string.clone()); + let actual_len = length(&db, input); + assert_eq!(new_len, actual_len); + }) + }); + } + + group.finish(); +} + +fn inputs(c: &mut Criterion) { + let mut group: codspeed_criterion_compat::BenchmarkGroup< + codspeed_criterion_compat::measurement::WallTime, + > = c.benchmark_group("Mutating Inputs"); + + let db = salsa::DatabaseImpl::default(); + + group.bench_function(BenchmarkId::new("new", "InternedInput"), |b| { + b.iter(|| { + let input: InternedInput = InternedInput::new(&db, "hello, world!".to_owned()); + interned_length(&db, input); + }) + }); + + group.bench_function(BenchmarkId::new("amortized", "InternedInput"), |b| { + let input = InternedInput::new(&db, "hello, world!".to_owned()); + let _ = interned_length(&db, input); + + b.iter(|| interned_length(&db, input)); + }); + + group.bench_function(BenchmarkId::new("new", "Input"), |b| { + b.iter(|| { + let input = Input::new(&db, "hello, world!".to_owned()); + length(&db, input); + }) + }); + + group.bench_function(BenchmarkId::new("amortized", "Input"), |b| { + let input = Input::new(&db, "hello, world!".to_owned()); + let _ = length(&db, input); + + b.iter(|| length(&db, input)); + }); + + group.finish(); +} + +criterion_group!(benches, mutating_inputs, inputs); +criterion_main!(benches); diff --git a/examples/lazy-input/main.rs b/examples/lazy-input/main.rs index 3b91888..792b7f3 100644 --- a/examples/lazy-input/main.rs +++ b/examples/lazy-input/main.rs @@ -1,3 +1,5 @@ +#![allow(unreachable_patterns)] +// FIXME(rust-lang/rust#129031): regression in nightly use std::{path::PathBuf, sync::Mutex, time::Duration}; use crossbeam::channel::{unbounded, Sender};