mod sim;
use std::time::Instant;
use crate::Fanout;
pub(crate) const WORKERS: usize = 8;
pub(crate) struct Pool;
impl Fanout for Pool {
fn workers(&self) -> usize {
WORKERS
}
fn for_each<T, F>(&self, items: &mut [T], body: F)
where
T: Send,
F: Fn(&mut T) + Send + Sync,
{
if items.len() < 2 {
items.iter_mut().for_each(body);
return;
}
let body = &body;
std::thread::scope(|scope| {
for item in items.iter_mut() {
scope.spawn(move || body(item));
}
});
}
}
const TARGET_NS: u128 = 200_000_000;
const MAX_ITERS: u64 = 1 << 20;
pub(crate) fn bench<R>(name: &str, items: u64, mut body: impl FnMut() -> R) {
let mut iters: u64 = 1;
loop {
let start = Instant::now();
for _ in 0..iters {
std::hint::black_box(body());
}
if start.elapsed().as_nanos() >= TARGET_NS || iters >= MAX_ITERS {
break;
}
iters = iters.saturating_mul(4).min(MAX_ITERS);
}
let start = Instant::now();
for _ in 0..iters {
std::hint::black_box(body());
}
let elapsed = start.elapsed();
let units = (iters * items.max(1)) as f64;
let per_item_ns = elapsed.as_secs_f64() * 1e9 / units;
std::println!(" {name:<40} {per_item_ns:>10.2} ns/item");
}