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
//! Measurement of average call time using fixed-size execution rounds.

use std::marker::PhantomData;

use ::Sample;
use benchmark::Benchmark;
use black_box::black_box;
use runner::Runner;
use timer::Timer;


/// Default number of executions per round.
pub const DEFAULT_ROUND_SIZE: usize = 10_000;

/// Default number of rounds to run and record.
pub const DEFAULT_SAMPLE_SIZE: usize = 100;

/// Runs multiple rounds of executions of a target, recording the average target
/// execution time in each round.
pub struct FixedRunner<T: Timer> {
    round_size: usize,
    sample_size: usize,
    _timer: PhantomData<T>,
}

impl<T: Timer> FixedRunner<T> {
    /// Construct a `FixedRunner` that will record a sample of its target with
    /// `sample_size` timing measurements. Each measurement will be the average
    /// time per call after executing the target `round_size` times.
    pub fn new(round_size: usize, sample_size: usize) -> Self {
        FixedRunner {
            round_size,
            sample_size,
            _timer: PhantomData,
        }
    }

    fn run_round<B, Ret>(&mut self, round_size: usize, bench: &mut B) -> f64
    where
        B: Benchmark<Ret>,
    {
        let mut start = T::new_timer();
        let mut end = T::new_timer();

        start.mark();
        for _ in 0..round_size {
            black_box(bench.target());
        }
        end.mark();

        end.since(&start) / (round_size as f64)
    }
}

impl<T: Timer> Runner<f64> for FixedRunner<T> {
    fn run<B, Ret>(&mut self, bench: &mut B) -> Sample<f64>
    where
        B: Benchmark<Ret>,
    {

        let mut data = Vec::with_capacity(self.sample_size);

        let round_size = self.round_size;  // For borrowck.
        for _ in 0..self.sample_size {
            data.push(self.run_round(round_size, bench))
        }

        Sample { name: bench.name(), data }
    }
}