use std::{
future::Future,
hint::black_box,
pin::Pin,
task::{Context, Poll, Waker},
};
use criterion::{BatchSize, Criterion, Throughput, criterion_group, criterion_main};
use zruntime::{
Event, EventListener,
lock::{Mutex, Semaphore},
};
fn event_benches(c: &mut Criterion) {
let mut group = c.benchmark_group("event");
let listen = Event::new();
listen.notify(0);
group.bench_function("listen", |b| {
b.iter_batched(
|| (),
|()| listen.listen(),
BatchSize::NumIterations(LISTENERS_PER_BATCH),
);
});
let listen_drop = Event::new();
listen_drop.notify(0);
group.bench_function("listen-drop", |b| {
b.iter(|| drop(black_box(listen_drop.listen())));
});
let notify_none = Event::new();
notify_none.notify(0);
group.bench_function("notify-none", |b| {
b.iter(|| black_box(notify_none.notify(1)));
});
let uncontended = Mutex::new(());
group.bench_function("mutex/uncontended", |b| {
b.iter(|| drop(black_box(uncontended.try_lock())));
});
let semaphore = Semaphore::new(1);
group.bench_function("semaphore/uncontended", |b| {
b.iter(|| drop(black_box(semaphore.try_acquire())));
});
group.bench_function("wake-one", |b| {
b.iter_batched(
|| listened_to(1),
|(event, mut listeners)| {
assert_eq!(event.notify(1), 1);
assert!(poll_once(&mut listeners[0]).is_ready());
(event, listeners)
},
BatchSize::NumIterations(LISTENERS_PER_BATCH),
);
});
group.throughput(Throughput::Elements(100));
group.bench_function("wake-all/100", |b| {
b.iter_batched(
|| listened_to(100),
|(event, mut listeners)| {
assert_eq!(event.notify(usize::MAX), 100);
for listener in &mut listeners {
assert!(poll_once(listener).is_ready());
}
(event, listeners)
},
BatchSize::SmallInput,
);
});
group.finish();
}
fn listened_to(count: usize) -> (Event, Vec<EventListener>) {
let event = Event::new();
let listeners = (0..count).map(|_| event.listen()).collect();
(event, listeners)
}
fn poll_once(listener: &mut EventListener) -> Poll<()> {
Pin::new(listener).poll(&mut Context::from_waker(Waker::noop()))
}
const LISTENERS_PER_BATCH: u64 = 64;
criterion_group!(benches, event_benches);
criterion_main!(benches);