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
extern crate criterion;

pub use criterion::Criterion;
pub use criterion::black_box;

/// Stand-in for `bencher::Bencher` which uses Criterion.rs to perform the benchmark instead.
pub struct Bencher<'a> {
    pub bytes: u64,
    pub bencher: &'a mut ::criterion::Bencher,
}
impl<'a> Bencher<'a> {
    /// Callback for benchmark functions to run to perform the benchmark
    pub fn iter<T, F>(&mut self, inner: F)
        where F: FnMut() -> T
    {
        self.bencher.iter(inner);
    }
}

/// Stand-in for `bencher::benchmark_group!` which performs benchmarks using Criterion.rs instead.
#[macro_export]
macro_rules! benchmark_group {
    ($group_name:ident, $($function:path),+) => {
        pub fn $group_name() {
            use $crate::Criterion;
            let mut criterion: Criterion = Criterion::default().configure_from_args();

            $(
                criterion.bench_function(stringify!($function), |b| {
                    let mut wrapped = $crate::Bencher {
                        bytes: 0,
                        bencher: b,
                    };

                    $function(&mut wrapped);
                });
            )+
        }
    };
    ($group_name:ident, $($function:path,)+) => {
        benchmark_group!($group_name, $($function),+);
    };
}

/// Stand-in for `bencher::benchmark_main!` which performs benchmarks using Criterion.rs instead.
#[macro_export]
macro_rules! benchmark_main {
    ($($group_name:path),+) => {
        fn main() {
            $(
                $group_name();
            )+

            $crate::Criterion::default()
                .configure_from_args()
                .final_summary();
        }
    };
    ($($group_name:path,)+) => {
        benchmark_main!($($group_name),+);
    };
}