1 /*
2  *  Created by Joachim on 16/04/2019.
3  *  Adapted from donated nonius code.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 
9  // Execution plan
10 
11 #ifndef TWOBLUECUBES_CATCH_EXECUTION_PLAN_HPP_INCLUDED
12 #define TWOBLUECUBES_CATCH_EXECUTION_PLAN_HPP_INCLUDED
13 
14 #include "../catch_config.hpp"
15 #include "catch_clock.hpp"
16 #include "catch_environment.hpp"
17 #include "detail/catch_benchmark_function.hpp"
18 #include "detail/catch_repeat.hpp"
19 #include "detail/catch_run_for_at_least.hpp"
20 
21 #include <algorithm>
22 
23 namespace Catch {
24     namespace Benchmark {
25         template <typename Duration>
26         struct ExecutionPlan {
27             int iterations_per_sample;
28             Duration estimated_duration;
29             Detail::BenchmarkFunction benchmark;
30             Duration warmup_time;
31             int warmup_iterations;
32 
33             template <typename Duration2>
operator ExecutionPlan<Duration2>Catch::Benchmark::ExecutionPlan34             operator ExecutionPlan<Duration2>() const {
35                 return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };
36             }
37 
38             template <typename Clock>
runCatch::Benchmark::ExecutionPlan39             std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
40                 // warmup a bit
41                 Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));
42 
43                 std::vector<FloatDuration<Clock>> times;
44                 times.reserve(cfg.benchmarkSamples());
45                 std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {
46                     Detail::ChronometerModel<Clock> model;
47                     this->benchmark(Chronometer(model, iterations_per_sample));
48                     auto sample_time = model.elapsed() - env.clock_cost.mean;
49                     if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();
50                     return sample_time / iterations_per_sample;
51                 });
52                 return times;
53             }
54         };
55     } // namespace Benchmark
56 } // namespace Catch
57 
58 #endif // TWOBLUECUBES_CATCH_EXECUTION_PLAN_HPP_INCLUDED
59