use std::{ io::BufReader, sync::{ atomic::{AtomicBool, Ordering}, Arc, }, time::Duration, }; use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; use rustls::sign::CertifiedKey; use rustls_channel_resolver::channel; fn prepare_key() -> CertifiedKey { let certfile = std::fs::File::open("./out/example.crt").unwrap(); let mut reader = BufReader::new(certfile); let certs = rustls_pemfile::certs(&mut reader) .map(|res| res.map(|c| rustls::Certificate(c.to_vec()))) .collect::, _>>() .unwrap(); let keyfile = std::fs::File::open("./out/example.key").unwrap(); let mut reader = BufReader::new(keyfile); let private_key = rustls_pemfile::private_key(&mut reader).unwrap().unwrap(); let private_key = rustls::sign::any_supported_type(&rustls::PrivateKey(Vec::from(private_key.secret_der()))) .unwrap(); CertifiedKey::new(certs, private_key) } fn parallel_bench(c: &mut Criterion, name: &str, writer: bool, sleep: bool) { let mut group = c.benchmark_group(name); for i in [1u64, 2, 4, 8, 16, 32, 64].iter() { group.bench_with_input(BenchmarkId::from_parameter(i), i, |b, i| { let key = prepare_key(); let (tx, rx) = channel::(key.clone()); let go = Arc::new(AtomicBool::new(true)); let mut handles = (0..*i) .map(|_| { let rx = rx.clone(); let go = go.clone(); std::thread::spawn(move || { while go.load(Ordering::Relaxed) { let _key = black_box(rx.read()); } }) }) .collect::>(); if writer { let go = go.clone(); handles.push(std::thread::spawn(move || { while go.load(Ordering::Relaxed) { tx.update(key.clone()); if sleep { std::thread::sleep(Duration::from_micros(1)); } } })); } b.iter(|| { let _key = black_box(rx.read()); }); go.store(false, Ordering::Relaxed); for handle in handles { handle.join().unwrap(); } }); } group.finish(); } pub fn criterion_benchmark(c: &mut Criterion) { c.bench_function("sequential_access", |b| { let (_, rx) = channel::<1>(prepare_key()); b.iter(|| { let _key = black_box(rx.read()); }) }); parallel_bench::<4>(c, "parallel_access_4", false, false); parallel_bench::<8>(c, "parallel_access_8", false, false); parallel_bench::<16>(c, "parallel_access_16", false, false); parallel_bench::<32>(c, "parallel_access_32", false, false); parallel_bench::<64>(c, "parallel_access_64", false, false); parallel_bench::<4>(c, "parallel_access_with_writer_4", true, false); parallel_bench::<8>(c, "parallel_access_with_writer_8", true, false); parallel_bench::<16>(c, "parallel_access_with_writer_16", true, false); parallel_bench::<32>(c, "parallel_access_with_writer_32", true, false); parallel_bench::<64>(c, "parallel_access_with_writer_64", true, false); parallel_bench::<4>(c, "parallel_access_with_writer_sleep_4", true, true); parallel_bench::<8>(c, "parallel_access_with_writer_sleep_8", true, true); parallel_bench::<16>(c, "parallel_access_with_writer_sleep_16", true, true); parallel_bench::<32>(c, "parallel_access_with_writer_sleep_32", true, true); parallel_bench::<64>(c, "parallel_access_with_writer_sleep_64", true, true); } criterion_group!(benches, criterion_benchmark); criterion_main!(benches);