use criterion::{black_box, criterion_main, Criterion}; use turborand::prelude::*; #[cfg(feature = "wyrand")] fn turborand_cell_benchmark(c: &mut Criterion) { c.bench_function("CellRng new", |b| b.iter(|| black_box(Rng::default()))); c.bench_function("CellRng clone", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.clone())) }); c.bench_function("CellRng fork", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.fork())) }); c.bench_function("CellRng fill_bytes", |b| { let rand = Rng::default(); let data = [0u8; 24]; b.iter_batched( || data, |mut data| rand.fill_bytes(&mut data), criterion::BatchSize::SmallInput, ) }); c.bench_function("CellRng fill_bytes large", |b| { let rand = Rng::default(); let data = [0u8; 2048]; b.iter_batched_ref( || data, |data| rand.fill_bytes(data), criterion::BatchSize::LargeInput, ) }); c.bench_function("CellRng gen_u128", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.gen_u128())); }); c.bench_function("CellRng gen_u64", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.gen_u64())); }); c.bench_function("CellRng gen_u32", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.gen_u32())); }); c.bench_function("CellRng gen_u16", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.gen_u16())); }); c.bench_function("CellRng gen_u8", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.gen_u8())); }); c.bench_function("CellRng bool", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.bool())); }); c.bench_function("CellRng usize range", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.usize(..20))); }); c.bench_function("CellRng index", |b| { let rand = Rng::default(); let bound = 20; b.iter(|| black_box(rand.index(..bound))); }); c.bench_function("CellRng isize range", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.isize(-10..10))); }); c.bench_function("CellRng u128 bounded range", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.u128(..20))); }); c.bench_function("CellRng i128 bounded range", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.i128(-20..20))); }); c.bench_function("CellRng u64 bounded range", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.u64(..20))); }); c.bench_function("CellRng i32 bounded range", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.i32(-20..20))); }); c.bench_function("CellRng f64", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.f64())); }); c.bench_function("CellRng f32", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.f32())); }); c.bench_function("CellRng f64 normalized", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.f64_normalized())); }); c.bench_function("CellRng f32 normalized", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.f32_normalized())); }); c.bench_function("CellRng char", |b| { let rand = Rng::default(); b.iter(|| black_box(rand.char('a'..='Ç'))); }); c.bench_function("CellRng sample", |b| { let rand = Rng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample(&data))) }); c.bench_function("CellRng sample one", |b| { let rand = Rng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample(&data[0..1]))) }); c.bench_function("CellRng sample iter", |b| { let rand = Rng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample_iter(data.iter()))) }); c.bench_function("CellRng sample iter one", |b| { let rand = Rng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample_iter(data[0..1].iter()))) }); c.bench_function("CellRng shuffle small", |b| { let rand = Rng::default(); let mut data = [0.0; 8]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| rand.shuffle(&mut data)) }); c.bench_function("CellRng shuffle large", |b| { let rand = Rng::default(); let mut data = vec![0.0; u16::MAX as usize]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| rand.shuffle(&mut data)) }); c.bench_function("CellRng shuffle xlarge", |b| { let rand = Rng::default(); let mut data = vec![0.0; (u16::MAX as usize) * 10]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| rand.shuffle(&mut data)) }); c.bench_function("CellRng weighted sample", |b| { let rand = Rng::default(); let mut data = [0.0; 2048]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| black_box(rand.weighted_sample(&data, |(&item, _)| item))) }); c.bench_function("CellRng weighted sample mut", |b| { let rand = Rng::default(); let mut data = [0.0; 2048]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| { let _ = rand.weighted_sample_mut(&mut data, |(&item, _)| item); }) }); } #[cfg(feature = "atomic")] fn turborand_atomic_benchmark(c: &mut Criterion) { c.bench_function("AtomicRng new", |b| { b.iter(|| black_box(AtomicRng::default())) }); c.bench_function("AtomicRng clone", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.clone())) }); c.bench_function("AtomicRng fork", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.fork())) }); c.bench_function("AtomicRng fill_bytes", |b| { let rand = AtomicRng::default(); let data = [0u8; 24]; b.iter_batched( || data, |mut data| rand.fill_bytes(&mut data), criterion::BatchSize::SmallInput, ) }); c.bench_function("AtomicRng fill_bytes large", |b| { let rand = AtomicRng::default(); let data = [0u8; 2048]; b.iter_batched_ref( || data, |data| rand.fill_bytes(data), criterion::BatchSize::LargeInput, ) }); c.bench_function("AtomicRng gen_u128", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.gen_u128())); }); c.bench_function("AtomicRng gen_u64", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.gen_u64())); }); c.bench_function("AtomicRng gen_u32", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.gen_u32())); }); c.bench_function("AtomicRng gen_u16", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.gen_u16())); }); c.bench_function("AtomicRng gen_u8", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.gen_u8())); }); c.bench_function("AtomicRng bool", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.bool())); }); c.bench_function("AtomicRng usize range", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.usize(..20))); }); c.bench_function("AtomicRng index", |b| { let rand = AtomicRng::default(); let bound = 20; b.iter(|| black_box(rand.index(..bound))); }); c.bench_function("AtomicRng isize range", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.isize(-10..10))); }); c.bench_function("AtomicRng u128 bounded range", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.u128(..20))); }); c.bench_function("AtomicRng i128 bounded range", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.i128(-20..20))); }); c.bench_function("AtomicRng u64 bounded range", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.u64(..20))); }); c.bench_function("AtomicRng i32 bounded range", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.i32(-20..20))); }); c.bench_function("AtomicRng f64", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.f64())); }); c.bench_function("AtomicRng f32", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.f32())); }); c.bench_function("AtomicRng f64 normalized", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.f64_normalized())); }); c.bench_function("AtomicRng f32 normalized", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.f32_normalized())); }); c.bench_function("AtomicRng char", |b| { let rand = AtomicRng::default(); b.iter(|| black_box(rand.char('a'..='Ç'))); }); c.bench_function("AtomicRng sample", |b| { let rand = AtomicRng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample(&data))) }); c.bench_function("AtomicRng sample one", |b| { let rand = AtomicRng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample(&data[0..1]))) }); c.bench_function("AtomicRng sample iter", |b| { let rand = AtomicRng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample_iter(data.iter()))) }); c.bench_function("AtomicRng sample iter one", |b| { let rand = AtomicRng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample_iter(data[0..1].iter()))) }); c.bench_function("AtomicRng shuffle small", |b| { let rand = AtomicRng::default(); let mut data = [0.0; 8]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| rand.shuffle(&mut data)) }); c.bench_function("AtomicRng shuffle large", |b| { let rand = AtomicRng::default(); let mut data = vec![0.0; u16::MAX as usize]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| rand.shuffle(&mut data)) }); c.bench_function("AtomicRng shuffle xlarge", |b| { let rand = AtomicRng::default(); let mut data = vec![0.0; (u16::MAX as usize) * 10]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| rand.shuffle(&mut data)) }); c.bench_function("AtomicRng weighted sample", |b| { let rand = AtomicRng::default(); let mut data = [0.0; 2048]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| black_box(rand.weighted_sample(&data, |(&item, _)| item))) }); c.bench_function("AtomicRng weighted sample mut", |b| { let rand = AtomicRng::default(); let mut data = [0.0; 2048]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| { let _ = rand.weighted_sample_mut(&mut data, |(&item, _)| item); }) }); } #[cfg(feature = "chacha")] fn turborand_chacha_benchmark(c: &mut Criterion) { c.bench_function("ChaChaRng new", |b| { b.iter(|| black_box(ChaChaRng::default())); }); c.bench_function("ChaChaRng clone", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.clone())); }); c.bench_function("ChaChaRng fork", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.fork())); }); c.bench_function("ChaChaRng fill_bytes", |b| { let rand = ChaChaRng::default(); let data = [0u8; 24]; b.iter_batched( || data, |mut data| rand.fill_bytes(&mut data), criterion::BatchSize::SmallInput, ) }); c.bench_function("ChaChaRng fill_bytes large", |b| { let rand = ChaChaRng::default(); let data = [0u8; 2048]; b.iter_batched_ref( || data, |data| rand.fill_bytes(data), criterion::BatchSize::LargeInput, ) }); c.bench_function("ChaChaRng gen_u128", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.gen_u128())); }); c.bench_function("ChaChaRng gen_u64", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.gen_u64())); }); c.bench_function("ChaChaRng gen_u32", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.gen_u32())); }); c.bench_function("ChaChaRng gen_u16", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.gen_u16())); }); c.bench_function("ChaChaRng gen_u8", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.gen_u8())); }); c.bench_function("ChaChaRng bool", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.bool())); }); c.bench_function("ChaChaRng usize range", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.usize(..20))); }); c.bench_function("ChaChaRng index", |b| { let rand = ChaChaRng::default(); let bound = 20; b.iter(|| black_box(rand.index(..bound))); }); c.bench_function("ChaChaRng isize range", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.isize(-10..10))); }); c.bench_function("ChaChaRng u128 bounded range", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.u128(..20))); }); c.bench_function("ChaChaRng i128 bounded range", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.i128(-20..20))); }); c.bench_function("ChaChaRng u64 bounded range", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.u64(..20))); }); c.bench_function("ChaChaRng i32 bounded range", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.i32(-20..20))); }); c.bench_function("ChaChaRng f64", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.f64())); }); c.bench_function("ChaChaRng f32", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.f32())); }); c.bench_function("ChaChaRng f64 normalized", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.f64_normalized())); }); c.bench_function("ChaChaRng f32 normalized", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.f32_normalized())); }); c.bench_function("ChaChaRng char", |b| { let rand = ChaChaRng::default(); b.iter(|| black_box(rand.char('a'..='Ç'))); }); c.bench_function("ChaChaRng sample", |b| { let rand = ChaChaRng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample(&data))) }); c.bench_function("ChaChaRng sample one", |b| { let rand = ChaChaRng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample(&data[0..1]))) }); c.bench_function("ChaChaRng sample iter", |b| { let rand = ChaChaRng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample_iter(data.iter()))) }); c.bench_function("ChaChaRng sample iter one", |b| { let rand = ChaChaRng::default(); let mut data = [0u8; 2048]; rand.fill_bytes(&mut data); b.iter(|| black_box(rand.sample_iter(data[0..1].iter()))) }); c.bench_function("ChaChaRng shuffle small", |b| { let rand = ChaChaRng::default(); let mut data = [0.0; 8]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| rand.shuffle(&mut data)) }); c.bench_function("ChaChaRng shuffle large", |b| { let rand = ChaChaRng::default(); let mut data = vec![0.0; u16::MAX as usize]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| rand.shuffle(&mut data)) }); c.bench_function("ChaChaRng shuffle xlarge", |b| { let rand = ChaChaRng::default(); let mut data = vec![0.0; (u16::MAX as usize) * 10]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| rand.shuffle(&mut data)) }); c.bench_function("ChaChaRng weighted sample", |b| { let rand = ChaChaRng::default(); let mut data = [0.0; 2048]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| black_box(rand.weighted_sample(&data, |(&item, _)| item))) }); c.bench_function("ChaChaRng weighted sample mut", |b| { let rand = ChaChaRng::default(); let mut data = [0.0; 2048]; data.iter_mut().for_each(|slot| *slot = rand.f64()); b.iter(|| { let _ = rand.weighted_sample_mut(&mut data, |(&item, _)| item); }) }); } pub fn benches() { let mut criterion: Criterion<_> = Criterion::default().configure_from_args(); #[cfg(feature = "wyrand")] turborand_cell_benchmark(&mut criterion); #[cfg(feature = "atomic")] turborand_atomic_benchmark(&mut criterion); #[cfg(feature = "chacha")] turborand_chacha_benchmark(&mut criterion); } criterion_main!(benches);