aboutsummaryrefslogtreecommitdiff
path: root/primrose/crates/candelabra-benchmarker/src/stack.rs
diff options
context:
space:
mode:
Diffstat (limited to 'primrose/crates/candelabra-benchmarker/src/stack.rs')
-rw-r--r--primrose/crates/candelabra-benchmarker/src/stack.rs89
1 files changed, 89 insertions, 0 deletions
diff --git a/primrose/crates/candelabra-benchmarker/src/stack.rs b/primrose/crates/candelabra-benchmarker/src/stack.rs
new file mode 100644
index 0000000..4010cae
--- /dev/null
+++ b/primrose/crates/candelabra-benchmarker/src/stack.rs
@@ -0,0 +1,89 @@
+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};
+
+pub trait StackExt<E> {
+ /// Benchmark at the given `ns`.
+ fn benchmark_stack(ns: &[usize]) -> Results;
+
+ /// 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<T, E> StackExt<E> for T
+where
+ T: Stack<E> + Default,
+ Standard: Distribution<E>,
+{
+ fn benchmark_stack(ns: &[usize]) -> Results {
+ debug!(
+ "Benchmarking {} at {} different n values",
+ type_name::<T>(),
+ ns.len()
+ );
+
+ let mut by_n = HashMap::new();
+ for n in ns {
+ by_n.insert(*n, Self::benchmark_stack_at(*n));
+ }
+
+ Results { by_n }
+ }
+
+ fn benchmark_stack_at(n: usize) -> SingleNResults {
+ let mut by_op = HashMap::new();
+
+ debug!("Benchmarking {} at n = {}", type_name::<T>(), 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());
+ },
+ )
+ }
+}