aboutsummaryrefslogtreecommitdiff
path: root/primrose/crates/candelabra-benchmarker/src/stack.rs
blob: f6b32f0f2efe1149eae944db217f061228984eb5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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<E> {
    /// 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_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());
            },
        )
    }
}