Skip to content
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
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())
});
}
}
}
Loading