use std::time::{Duration, Instant};
fn main() {
let iters = std::env::args()
.nth(1)
.and_then(|value| value.parse::<usize>().ok())
.unwrap_or(20_000);
llam::Runtime::builder()
.profile(llam::Profile::ReleaseFast)
.run(move || {
bench_spawn_join(iters)?;
bench_channel_pingpong(iters)?;
bench_select_default(iters)?;
Ok(())
})
.expect("LLAM-rs benchmark failed");
}
fn report(name: &str, iters: usize, elapsed: Duration) {
let seconds = elapsed.as_secs_f64().max(1e-9);
let ops = iters as f64 / seconds;
println!("{name:20} {ops:12.2} ops/s elapsed={elapsed:?}");
}
fn bench_spawn_join(iters: usize) -> llam::Result<()> {
let start = Instant::now();
for _ in 0..iters {
let handle = llam::spawn!({ 1usize });
assert_eq!(handle.join().expect("join failed"), 1);
}
report("spawn_join", iters, start.elapsed());
Ok(())
}
fn bench_channel_pingpong(iters: usize) -> llam::Result<()> {
let (tx_a, rx_a) = llam::channel::bounded::<usize>(1)?;
let (tx_b, rx_b) = llam::channel::bounded::<usize>(1)?;
let peer = llam::spawn!(move {
for _ in 0..iters {
let value = rx_a.recv().unwrap();
tx_b.send(value + 1).unwrap();
}
});
let start = Instant::now();
for i in 0..iters {
tx_a.send(i).expect("send failed");
assert_eq!(rx_b.recv()?, i + 1);
}
peer.join().expect("peer join failed");
report("channel_pingpong", iters, start.elapsed());
Ok(())
}
fn bench_select_default(iters: usize) -> llam::Result<()> {
let (_tx, rx) = llam::channel::bounded::<usize>(1)?;
let start = Instant::now();
let mut hits = 0usize;
for _ in 0..iters {
let defaulted = llam::select! {
recv(rx) -> value => {
let _ = value;
false
},
default => {
true
},
};
hits += usize::from(defaulted);
}
assert_eq!(hits, iters);
report("select_default", iters, start.elapsed());
Ok(())
}