use std::time::Instant;
const BATCHES: usize = 100;
const SPAWNS_PER_BATCH: usize = 6;
fn trivial_work(seed: u64) -> u64 {
let mut acc = seed;
for _ in 0..1000 {
acc = acc.wrapping_mul(6364136223846793005).wrapping_add(1);
}
acc
}
fn bench_std_thread_scope() -> u64 {
let mut total = 0u64;
for b in 0..BATCHES {
std::thread::scope(|s| {
let handles: Vec<_> = (0..SPAWNS_PER_BATCH)
.map(|i| s.spawn(move || trivial_work((b * SPAWNS_PER_BATCH + i) as u64)))
.collect();
for h in handles {
total = total.wrapping_add(h.join().unwrap());
}
});
}
total
}
fn bench_rayon_scope() -> u64 {
let mut total = 0u64;
for b in 0..BATCHES {
rayon::scope(|s| {
let (tx, rx) = std::sync::mpsc::channel();
for i in 0..SPAWNS_PER_BATCH {
let tx = tx.clone();
s.spawn(move |_| {
let r = trivial_work((b * SPAWNS_PER_BATCH + i) as u64);
tx.send(r).unwrap();
});
}
drop(tx);
for r in rx {
total = total.wrapping_add(r);
}
});
}
total
}
fn main() {
rayon::scope(|s| s.spawn(|_| {}));
let t0 = Instant::now();
let a = bench_std_thread_scope();
let std_elapsed = t0.elapsed();
let t1 = Instant::now();
let b = bench_rayon_scope();
let rayon_elapsed = t1.elapsed();
println!(
"std::thread::scope : {:>8.3}ms ({} spawns, checksum={a})",
std_elapsed.as_secs_f64() * 1000.0,
BATCHES * SPAWNS_PER_BATCH,
);
println!(
"rayon::scope : {:>8.3}ms ({} spawns, checksum={b})",
rayon_elapsed.as_secs_f64() * 1000.0,
BATCHES * SPAWNS_PER_BATCH,
);
println!(
"ratio (std/rayon) : {:.2}x",
std_elapsed.as_secs_f64() / rayon_elapsed.as_secs_f64()
);
}