use std::hint::black_box;
use std::task::Poll;
use bytes::Bytes;
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use moq_net::{Timestamp, broadcast, cache, track};
const FANOUT: [usize; 4] = [1, 8, 64, 512];
const PAYLOAD: usize = 64;
const CACHE_CAPACITY: u64 = 64 * 1024;
struct Fanout {
_broadcast: broadcast::Producer,
track: track::Producer,
subscribers: Vec<track::Subscriber>,
waiters: Vec<kio::Waiter>,
payload: Bytes,
}
impl Fanout {
fn new(subscribers: usize) -> Self {
let mut info = broadcast::Info::default();
info.origin.pool = cache::Pool::new(CACHE_CAPACITY);
let mut broadcast = broadcast::Producer::new(info);
let track = broadcast.create_track("bench", None).unwrap();
let mut subscribers: Vec<_> = (0..subscribers).map(|_| track.subscribe(None)).collect();
let waiters: Vec<_> = (0..subscribers.len()).map(|_| kio::Waiter::noop()).collect();
for (subscriber, waiter) in subscribers.iter_mut().zip(&waiters) {
assert!(matches!(subscriber.poll_recv_group(waiter), Poll::Pending));
}
Self {
_broadcast: broadcast,
track,
subscribers,
waiters,
payload: Bytes::from(vec![0; PAYLOAD]),
}
}
fn cycle(&mut self) {
let mut group = self.track.append_group().unwrap();
group.write_frame(Timestamp::ZERO, self.payload.clone()).unwrap();
group.finish().unwrap();
for (subscriber, waiter) in self.subscribers.iter_mut().zip(&self.waiters) {
let group = match subscriber.poll_recv_group(waiter) {
Poll::Ready(Ok(Some(group))) => group,
_ => unreachable!("a completed group must be ready"),
};
black_box(group);
assert!(matches!(subscriber.poll_recv_group(waiter), Poll::Pending));
}
}
}
fn bench_fanout(c: &mut Criterion) {
let mut group = c.benchmark_group("track_fanout_group");
for subscribers in FANOUT {
group.throughput(Throughput::Elements(subscribers as u64));
group.bench_with_input(
BenchmarkId::from_parameter(subscribers),
&subscribers,
|b, &subscribers| {
let mut fanout = Fanout::new(subscribers);
b.iter(|| fanout.cycle());
},
);
}
group.finish();
}
criterion_group!(benches, bench_fanout);
criterion_main!(benches);