| 7070 | namespace Catch { |
| 7071 | namespace Benchmark { |
| 7072 | struct Benchmark { |
| 7073 | Benchmark(std::string &&name) |
| 7074 | : name(std::move(name)) {} |
| 7075 | |
| 7076 | template <class FUN> |
| 7077 | Benchmark(std::string &&name, FUN &&func) |
| 7078 | : fun(std::move(func)), name(std::move(name)) {} |
| 7079 | |
| 7080 | template <typename Clock> |
| 7081 | ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const { |
| 7082 | auto min_time = env.clock_resolution.mean * Detail::minimum_ticks; |
| 7083 | auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time)); |
| 7084 | auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun); |
| 7085 | int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed)); |
| 7086 | return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations }; |
| 7087 | } |
| 7088 | |
| 7089 | template <typename Clock = default_clock> |
| 7090 | void run() { |
| 7091 | IConfigPtr cfg = getCurrentContext().getConfig(); |
| 7092 | |
| 7093 | auto env = Detail::measure_environment<Clock>(); |
| 7094 | |
| 7095 | getResultCapture().benchmarkPreparing(name); |
| 7096 | CATCH_TRY{ |
| 7097 | auto plan = user_code([&] { |
| 7098 | return prepare<Clock>(*cfg, env); |
| 7099 | }); |
| 7100 | |
| 7101 | BenchmarkInfo info { |
| 7102 | name, |
| 7103 | plan.estimated_duration.count(), |
| 7104 | plan.iterations_per_sample, |
| 7105 | cfg->benchmarkSamples(), |
| 7106 | cfg->benchmarkResamples(), |
| 7107 | env.clock_resolution.mean.count(), |
| 7108 | env.clock_cost.mean.count() |
| 7109 | }; |
| 7110 | |
| 7111 | getResultCapture().benchmarkStarting(info); |
| 7112 | |
| 7113 | auto samples = user_code([&] { |
| 7114 | return plan.template run<Clock>(*cfg, env); |
| 7115 | }); |
| 7116 | |
| 7117 | auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end()); |
| 7118 | BenchmarkStats<std::chrono::duration<double, std::nano>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance }; |
| 7119 | getResultCapture().benchmarkEnded(stats); |
| 7120 | |
| 7121 | } CATCH_CATCH_ALL{ |
| 7122 | if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow. |
| 7123 | std::rethrow_exception(std::current_exception()); |
| 7124 | } |
| 7125 | } |
| 7126 | |
| 7127 | // sets lambda to be used in fun *and* executes benchmark! |
| 7128 | template <typename Fun, |
nothing calls this directly
no test coverage detected