Skip to content

Commit

Permalink
Make criterion a benchmarking only dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
faern committed Feb 1, 2025
1 parent e800aca commit e2a2cdb
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 115 deletions.
12 changes: 10 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,20 @@ async = []
loom = { version = "0.7.2", features = ["futures"], optional = true }

[dev-dependencies]
criterion = "0.5.1"
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros", "time"] }
async-std = { version = "1", features = ["attributes"] }

# Benchmarking only dependency. This is hidden behind a `cfg(criterion)` to avoid it being
# pulled in during `cargo test` runs. Mostly because criterion has a much higher MSRV than
# this library, so it becomes impossible to run `cargo test` on the MSRV compiler without
# this hack.
# To run benchmarks, run with `RUSTFLAGS="--cfg criterion" cargo bench`
[target.'cfg(criterion)'.dev-dependencies]
criterion = "0.5.1"


[lints.rust]
unexpected_cfgs = { level = "deny", check-cfg = ['cfg(oneshot_loom)', 'cfg(oneshot_test_delay)'] }
unexpected_cfgs = { level = "deny", check-cfg = ['cfg(oneshot_loom)', 'cfg(oneshot_test_delay)', 'cfg(criterion)'] }

[[bench]]
name = "benches"
Expand Down
238 changes: 125 additions & 113 deletions benches/benches.rs
Original file line number Diff line number Diff line change
@@ -1,126 +1,138 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use std::mem;

criterion_group!(benches, bench);
criterion_main!(benches);

macro_rules! bench_send_and_recv {
($c:expr, $($type:ty => $value:expr);+) => {
// Sanity check that all $values are of $type.
$(let _: $type = $value;)*
{
let mut group = $c.benchmark_group("create_channel");
$(group.bench_function(stringify!($type), |b| {
b.iter(oneshot::channel::<$type>)
});)*
group.finish();
}
{
let mut group = $c.benchmark_group("create_and_send");
$(group.bench_function(stringify!($type), |b| {
b.iter(|| {
let (sender, _receiver) = oneshot::channel();
sender.send(black_box($value)).unwrap()
});
});)*
group.finish();
}
{
let mut group = $c.benchmark_group("create_and_send_on_closed");
$(group.bench_function(stringify!($type), |b| {
b.iter(|| {
let (sender, _) = oneshot::channel();
sender.send(black_box($value)).unwrap_err()
});
});)*
group.finish();
}
#[cfg(feature = "std")]
{
let mut group = $c.benchmark_group("create_send_and_recv");
$(group.bench_function(stringify!($type), |b| {
b.iter(|| {
let (sender, receiver) = oneshot::channel();
sender.send(black_box($value)).unwrap();
receiver.recv().unwrap()
});
});)*
group.finish();
}
#[cfg(feature = "std")]
{
let mut group = $c.benchmark_group("create_send_and_recv_ref");
$(group.bench_function(stringify!($type), |b| {
b.iter(|| {
let (sender, receiver) = oneshot::channel();
sender.send(black_box($value)).unwrap();
receiver.recv_ref().unwrap()
});
});)*
group.finish();
}
};
#[cfg(not(criterion))]
pub fn main() {
eprintln!(
"!!!!!! WARNING
To run benches, you neet to run with RUSTFLAGS=\"--cfg criterion\"
!!!!!! WARNING
"
);
}

fn bench(c: &mut Criterion) {
bench_send_and_recv!(c,
() => ();
u8 => 7u8;
u128 => 1234567u128;
[u8; 64] => [0b10101010u8; 64];
[u8; 4096] => [0b10101010u8; 4096]
);
#[cfg(criterion)]
criterion::criterion_group!(benches, imp::bench);
#[cfg(criterion)]
criterion::criterion_main!(benches);

bench_try_recv(c);
#[cfg(feature = "std")]
bench_recv_deadline_now(c);
#[cfg(feature = "std")]
bench_recv_timeout_zero(c);
}
#[cfg(criterion)]
mod imp {
macro_rules! bench_send_and_recv {
($c:expr, $($type:ty => $value:expr);+) => {
// Sanity check that all $values are of $type.
$(let _: $type = $value;)*
{
let mut group = $c.benchmark_group("create_channel");
$(group.bench_function(stringify!($type), |b| {
b.iter(oneshot::channel::<$type>)
});)*
group.finish();
}
{
let mut group = $c.benchmark_group("create_and_send");
$(group.bench_function(stringify!($type), |b| {
b.iter(|| {
let (sender, _receiver) = oneshot::channel();
sender.send(criterion::black_box($value)).unwrap()
});
});)*
group.finish();
}
{
let mut group = $c.benchmark_group("create_and_send_on_closed");
$(group.bench_function(stringify!($type), |b| {
b.iter(|| {
let (sender, _) = oneshot::channel();
sender.send(criterion::black_box($value)).unwrap_err()
});
});)*
group.finish();
}
#[cfg(feature = "std")]
{
let mut group = $c.benchmark_group("create_send_and_recv");
$(group.bench_function(stringify!($type), |b| {
b.iter(|| {
let (sender, receiver) = oneshot::channel();
sender.send(criterion::black_box($value)).unwrap();
receiver.recv().unwrap()
});
});)*
group.finish();
}
#[cfg(feature = "std")]
{
let mut group = $c.benchmark_group("create_send_and_recv_ref");
$(group.bench_function(stringify!($type), |b| {
b.iter(|| {
let (sender, receiver) = oneshot::channel();
sender.send(criterion::black_box($value)).unwrap();
receiver.recv_ref().unwrap()
});
});)*
group.finish();
}
};
}

fn bench_try_recv(c: &mut Criterion) {
let (sender, receiver) = oneshot::channel::<u128>();
c.bench_function("try_recv_empty", |b| {
b.iter(|| receiver.try_recv().unwrap_err())
});
mem::drop(sender);
c.bench_function("try_recv_empty_closed", |b| {
b.iter(|| receiver.try_recv().unwrap_err())
});
}
pub fn bench(c: &mut criterion::Criterion) {
bench_send_and_recv!(c,
() => ();
u8 => 7u8;
u128 => 1234567u128;
[u8; 64] => [0b10101010u8; 64];
[u8; 4096] => [0b10101010u8; 4096]
);

#[cfg(feature = "std")]
fn bench_recv_deadline_now(c: &mut Criterion) {
let now = std::time::Instant::now();
{
let (_sender, receiver) = oneshot::channel::<u128>();
c.bench_function("recv_deadline_now", |b| {
b.iter(|| receiver.recv_deadline(now).unwrap_err())
});
bench_try_recv(c);
#[cfg(feature = "std")]
bench_recv_deadline_now(c);
#[cfg(feature = "std")]
bench_recv_timeout_zero(c);
}
{

fn bench_try_recv(c: &mut criterion::Criterion) {
let (sender, receiver) = oneshot::channel::<u128>();
mem::drop(sender);
c.bench_function("recv_deadline_now_closed", |b| {
b.iter(|| receiver.recv_deadline(now).unwrap_err())
c.bench_function("try_recv_empty", |b| {
b.iter(|| receiver.try_recv().unwrap_err())
});
drop(sender);
c.bench_function("try_recv_empty_closed", |b| {
b.iter(|| receiver.try_recv().unwrap_err())
});
}
}

#[cfg(feature = "std")]
fn bench_recv_timeout_zero(c: &mut Criterion) {
let zero = std::time::Duration::from_nanos(0);
{
let (_sender, receiver) = oneshot::channel::<u128>();
c.bench_function("recv_timeout_zero", |b| {
b.iter(|| receiver.recv_timeout(zero).unwrap_err())
});
#[cfg(feature = "std")]
fn bench_recv_deadline_now(c: &mut criterion::Criterion) {
let now = std::time::Instant::now();
{
let (_sender, receiver) = oneshot::channel::<u128>();
c.bench_function("recv_deadline_now", |b| {
b.iter(|| receiver.recv_deadline(now).unwrap_err())
});
}
{
let (sender, receiver) = oneshot::channel::<u128>();
drop(sender);
c.bench_function("recv_deadline_now_closed", |b| {
b.iter(|| receiver.recv_deadline(now).unwrap_err())
});
}
}
{
let (sender, receiver) = oneshot::channel::<u128>();
mem::drop(sender);
c.bench_function("recv_timeout_zero_closed", |b| {
b.iter(|| receiver.recv_timeout(zero).unwrap_err())
});

#[cfg(feature = "std")]
fn bench_recv_timeout_zero(c: &mut criterion::Criterion) {
let zero = std::time::Duration::from_nanos(0);
{
let (_sender, receiver) = oneshot::channel::<u128>();
c.bench_function("recv_timeout_zero", |b| {
b.iter(|| receiver.recv_timeout(zero).unwrap_err())
});
}
{
let (sender, receiver) = oneshot::channel::<u128>();
drop(sender);
c.bench_function("recv_timeout_zero_closed", |b| {
b.iter(|| receiver.recv_timeout(zero).unwrap_err())
});
}
}
}

0 comments on commit e2a2cdb

Please sign in to comment.