chore: initial release v0.1.0
Runtime-agnostic oneshot broadcast channel for Rust.
This commit is contained in:
64 files changed
+23966
No files matched your search
@@ -0,0 +1,165 @@
|
||||
//! Runtime comparison benchmarks
|
||||
//!
|
||||
//! Compares announcement performance across different async runtimes.
|
||||
//! This verifies the runtime-agnostic design works consistently.
|
||||
//!
|
||||
//! Runtimes tested:
|
||||
//! - tokio (most popular)
|
||||
//! - smol (lightweight alternative)
|
||||
//!
|
||||
//! Expected result: Similar performance across runtimes since announcement
|
||||
//! uses event-listener which abstracts runtime details.
|
||||
|
||||
#![allow(unused_must_use)]
|
||||
|
||||
use announcement::Announcement;
|
||||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
|
||||
use std::hint::black_box;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Benchmark: Basic announce and listen - tokio vs smol
|
||||
fn bench_basic(c: &mut Criterion) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let mut group = c.benchmark_group("runtimes/basic");
|
||||
|
||||
// Tokio version
|
||||
group.bench_function("tokio", |b| {
|
||||
b.to_async(&rt).iter(|| async {
|
||||
let (announcer, announcement) = Announcement::new();
|
||||
let listener = announcement.listener();
|
||||
|
||||
let handle = tokio::spawn(async move { listener.listen().await });
|
||||
announcer.announce(Arc::new(42)).unwrap();
|
||||
|
||||
black_box(handle.await.unwrap());
|
||||
});
|
||||
});
|
||||
|
||||
// Smol version
|
||||
group.bench_function("smol", |b| {
|
||||
b.iter(|| {
|
||||
smol::block_on(async {
|
||||
let (announcer, announcement) = Announcement::new();
|
||||
let listener = announcement.listener();
|
||||
|
||||
let handle = smol::spawn(async move { listener.listen().await });
|
||||
announcer.announce(Arc::new(42)).unwrap();
|
||||
|
||||
black_box(handle.await);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
/// Benchmark: Fanout to multiple listeners - tokio vs smol
|
||||
fn bench_fanout(c: &mut Criterion) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let mut group = c.benchmark_group("runtimes/fanout");
|
||||
|
||||
for n in [10, 100, 500].iter() {
|
||||
group.throughput(Throughput::Elements(*n as u64));
|
||||
|
||||
// Tokio version
|
||||
group.bench_with_input(BenchmarkId::new("tokio", n), n, |b, &n| {
|
||||
b.to_async(&rt).iter(|| async move {
|
||||
let (announcer, announcement) = Announcement::new();
|
||||
|
||||
let mut handles = Vec::with_capacity(n);
|
||||
for _ in 0..n {
|
||||
let listener = announcement.listener();
|
||||
handles.push(tokio::spawn(async move { listener.listen().await }));
|
||||
}
|
||||
|
||||
announcer.announce(Arc::new(42)).unwrap();
|
||||
|
||||
for h in handles {
|
||||
black_box(h.await.unwrap());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Smol version
|
||||
group.bench_with_input(BenchmarkId::new("smol", n), n, |b, &n| {
|
||||
b.iter(|| {
|
||||
smol::block_on(async {
|
||||
let (announcer, announcement) = Announcement::new();
|
||||
|
||||
let mut handles = Vec::with_capacity(n);
|
||||
for _ in 0..n {
|
||||
let listener = announcement.listener();
|
||||
handles.push(smol::spawn(async move { listener.listen().await }));
|
||||
}
|
||||
|
||||
announcer.announce(Arc::new(42)).unwrap();
|
||||
|
||||
for h in handles {
|
||||
black_box(h.await);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
/// Benchmark: Concurrent announcements - tokio vs smol
|
||||
fn bench_concurrent(c: &mut Criterion) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let mut group = c.benchmark_group("runtimes/concurrent");
|
||||
|
||||
// Tokio version
|
||||
group.bench_function("tokio", |b| {
|
||||
b.to_async(&rt).iter(|| async {
|
||||
let mut handles = Vec::with_capacity(100);
|
||||
|
||||
for i in 0..100 {
|
||||
handles.push(tokio::spawn(async move {
|
||||
let (announcer, announcement) = Announcement::new();
|
||||
let listener = announcement.listener();
|
||||
|
||||
let recv_handle = tokio::spawn(async move { listener.listen().await });
|
||||
announcer.announce(Arc::new(i)).unwrap();
|
||||
|
||||
recv_handle.await.unwrap()
|
||||
}));
|
||||
}
|
||||
|
||||
for h in handles {
|
||||
black_box(h.await.unwrap());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Smol version
|
||||
group.bench_function("smol", |b| {
|
||||
b.iter(|| {
|
||||
smol::block_on(async {
|
||||
let mut handles = Vec::with_capacity(100);
|
||||
|
||||
for i in 0..100 {
|
||||
handles.push(smol::spawn(async move {
|
||||
let (announcer, announcement) = Announcement::new();
|
||||
let listener = announcement.listener();
|
||||
|
||||
let recv_handle = smol::spawn(async move { listener.listen().await });
|
||||
announcer.announce(Arc::new(i)).unwrap();
|
||||
|
||||
recv_handle.await
|
||||
}));
|
||||
}
|
||||
|
||||
for h in handles {
|
||||
black_box(h.await);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_basic, bench_fanout, bench_concurrent,);
|
||||
criterion_main!(benches);
|
||||
Reference in new issue
Block a user