use std::{any::type_name, collections::HashMap}; use log::debug; use primrose_library::traits::Stack; use rand::{distributions::Standard, prelude::Distribution, random}; use crate::{benchmark_op, Results, RunResults, SingleNResults}; /// Benchmark [`primrose_library::traits::Stack`] operations pub trait StackExt { /// Benchmark at a single `n`. fn benchmark_stack_at(n: usize) -> SingleNResults; /// Benchmark `push` at a single `n`. fn benchmark_stack_push(n: usize) -> RunResults; /// Benchmark `pop` at a single `n`. fn benchmark_stack_pop(n: usize) -> RunResults; } impl StackExt for T where T: Stack + Default, Standard: Distribution, { fn benchmark_stack_at(n: usize) -> SingleNResults { let mut by_op = HashMap::new(); debug!("Benchmarking {} at n = {}", type_name::(), n); debug!("...push"); by_op.insert("push", Self::benchmark_stack_push(n)); debug!("...pop"); by_op.insert("pop", Self::benchmark_stack_pop(n)); debug!("--- done!"); SingleNResults { by_op } } fn benchmark_stack_push(n: usize) -> RunResults { benchmark_op( || { let mut c = T::default(); for _ in 0..n { c.push(random()); } c }, |s| s.push(random()), |s| { s.pop(); }, ) } fn benchmark_stack_pop(n: usize) -> RunResults { benchmark_op( || { let mut c = T::default(); for _ in 0..n { c.push(random()); } c }, |s| { s.pop(); }, |s| { s.push(random()); }, ) } }