//! Stress test benchmarks for extreme scenarios //! //! Tests announcement under extreme conditions: //! - Million-scale operations (1M+ listeners/announcements) //! - Fully connected networks (N announcements × N listeners) //! - Cascade patterns (chain reactions and trees) use announcement::Announcement; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use std::hint::black_box; use std::sync::Arc; use std::time::Duration; /// Benchmark: Million scale stress - 1M announcements × 10 listeners fn bench_million_announcements(c: &mut Criterion) { let mut group = c.benchmark_group("stress/million_scale"); group.sample_size(10); group.measurement_time(Duration::from_secs(30)); group.bench_function("10K_announcements_x_10_listeners", |b| { b.iter(|| { let num_announcements = 10_000; let listeners_per_announcement = 10; let mut announcements = Vec::with_capacity(num_announcements); let mut announcers = Vec::with_capacity(num_announcements); // Create 10K announcement channels for _ in 0..num_announcements { let (tx, announcement) = Announcement::>::new(); announcers.push(tx); announcements.push(announcement); } // Create 10 listeners for each announcement (100K total) let mut all_listeners = Vec::with_capacity(num_announcements * listeners_per_announcement); for announcement in &announcements { for _ in 0..listeners_per_announcement { all_listeners.push(announcement.listener()); } } // Announce on all channels for (i, announcer) in announcers.into_iter().enumerate() { announcer.announce(Arc::new(i as i32)).unwrap(); } // Verify delivery (sampling for performance) for i in (0..all_listeners.len()).step_by(1000) { black_box(all_listeners[i].try_listen()); } }); }); group.finish(); } /// Benchmark: Single announcement to 10K listeners fn bench_one_to_million(c: &mut Criterion) { let mut group = c.benchmark_group("stress/one_to_ten_thousand"); group.sample_size(10); group.bench_function("1_announcement_x_10K_listeners", |b| { b.iter(|| { let (tx, announcement) = Announcement::new(); let num_listeners = 10_000; let mut listeners = Vec::with_capacity(num_listeners); for _ in 0..num_listeners { listeners.push(announcement.listener()); } tx.announce(Arc::new(42)).unwrap(); // Sample retrieval for i in (0..listeners.len()).step_by(1000) { black_box(listeners[i].try_listen()); } }); }); group.finish(); } /// Benchmark: Fully connected network - N announcements × N listeners fn bench_fully_connected(c: &mut Criterion) { let mut group = c.benchmark_group("stress/fully_connected"); group.sample_size(10); group.measurement_time(Duration::from_secs(10)); // N announcements each received by N listeners = N² connections for n in [10, 100, 500].iter() { let total_connections = n * n; group.throughput(Throughput::Elements(total_connections as u64)); group.bench_with_input(BenchmarkId::from_parameter(n), n, |b, &n| { b.iter(|| { // Create N announcement channels let mut announcements = Vec::with_capacity(n); let mut announcers = Vec::with_capacity(n); for _ in 0..n { let (tx, announcement) = Announcement::>::new(); announcers.push(tx); announcements.push(announcement); } // Create N listeners for each announcement (N² total listeners) let mut all_listeners = Vec::with_capacity(n * n); for announcement in &announcements { for _ in 0..n { all_listeners.push(announcement.listener()); } } // Announce on all channels for (i, announcer) in announcers.into_iter().enumerate() { announcer.announce(Arc::new(i as i32)).unwrap(); } // Retrieve all values for listener in &all_listeners { black_box(listener.try_listen()); } }); }); } group.finish(); } /// Benchmark: Cascade chain - A triggers B triggers C... fn bench_cascade_chain(c: &mut Criterion) { let mut group = c.benchmark_group("stress/cascade_chain"); for chain_length in [10, 100, 500].iter() { group.bench_with_input( BenchmarkId::from_parameter(chain_length), chain_length, |b, &n| { b.iter(|| { let mut announcements = Vec::with_capacity(n); let mut announcers = Vec::with_capacity(n); // Create chain of announcements for _ in 0..n { let (tx, announcement) = Announcement::>::new(); announcers.push(tx); announcements.push(announcement); } // Link chain: each announcement triggers next let listeners: Vec<_> = announcements .iter() .take(n - 1) .map(|a| a.listener()) .collect(); // Trigger cascade for (i, announcer) in announcers.into_iter().enumerate() { announcer.announce(Arc::new(i as i32)).unwrap(); } // Verify propagation for listener in &listeners { black_box(listener.try_listen()); } }); }, ); } group.finish(); } /// Benchmark: Cascade tree - A triggers B1, B2, B3... (tree fanout) fn bench_cascade_tree(c: &mut Criterion) { let mut group = c.benchmark_group("stress/cascade_tree"); for fanout in [2, 5, 10, 50].iter() { group.throughput(Throughput::Elements(*fanout as u64)); group.bench_with_input(BenchmarkId::from_parameter(fanout), fanout, |b, &fanout| { b.iter(|| { // Root announcement let (root_tx, root_announcement) = Announcement::>::new(); // Create fanout child announcements let mut child_announcers = Vec::with_capacity(fanout); let mut child_announcements = Vec::with_capacity(fanout); for _ in 0..fanout { let (tx, announcement) = Announcement::>::new(); child_announcers.push(tx); child_announcements.push(announcement); } // Root listener triggers all children let _root_listener = root_announcement.listener(); // Create listeners for all children let mut child_listeners = Vec::with_capacity(fanout); for announcement in &child_announcements { child_listeners.push(announcement.listener()); } // Trigger cascade root_tx.announce(Arc::new(0)).unwrap(); for (i, announcer) in child_announcers.into_iter().enumerate() { announcer.announce(Arc::new(i as i32)).unwrap(); } // Verify all children received for listener in &child_listeners { black_box(listener.try_listen()); } }); }); } group.finish(); } criterion_group!( benches, bench_million_announcements, bench_one_to_million, bench_fully_connected, bench_cascade_chain, bench_cascade_tree, ); criterion_main!(benches);