diff options
| author | Martin Hořeňovský | 2023-04-10 15:03:29 +0200 |
|---|---|---|
| committer | Martin Hořeňovský | 2023-05-01 13:21:41 +0200 |
| commit | fe64c28925d31292516ba0a172870e7deb3baad6 (patch) | |
| tree | d351b3a4f89a2ede0e5383c48072bf99c3b072dc /src | |
| parent | 7d07efc92b626da9d03223a3b5cfd5f80b7cc377 (diff) | |
| download | catch3-fe64c28925d31292516ba0a172870e7deb3baad6.tar.gz | |
Reduce compilation costs of benchmarks
We replaced some simple std::algorithm usage by loops, and reduced
header inclusion.
Diffstat (limited to 'src')
| -rw-r--r-- | src/catch2/benchmark/catch_execution_plan.hpp | 18 | ||||
| -rw-r--r-- | src/catch2/benchmark/catch_sample_analysis.hpp | 7 | ||||
| -rw-r--r-- | src/catch2/benchmark/detail/catch_analyse.hpp | 11 | ||||
| -rw-r--r-- | src/catch2/benchmark/detail/catch_estimate_clock.hpp | 20 | ||||
| -rw-r--r-- | src/catch2/benchmark/detail/catch_stats.cpp | 21 | ||||
| -rw-r--r-- | src/catch2/benchmark/detail/catch_stats.hpp | 16 |
6 files changed, 53 insertions, 40 deletions
diff --git a/src/catch2/benchmark/catch_execution_plan.hpp b/src/catch2/benchmark/catch_execution_plan.hpp index 039de7ee..4f60a646 100644 --- a/src/catch2/benchmark/catch_execution_plan.hpp +++ b/src/catch2/benchmark/catch_execution_plan.hpp @@ -17,8 +17,7 @@ #include <catch2/benchmark/detail/catch_repeat.hpp> #include <catch2/benchmark/detail/catch_run_for_at_least.hpp> -#include <algorithm> -#include <iterator> +#include <vector> namespace Catch { namespace Benchmark { @@ -41,14 +40,17 @@ namespace Catch { Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{})); std::vector<FloatDuration<Clock>> times; - times.reserve(cfg.benchmarkSamples()); - std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] { + const auto num_samples = cfg.benchmarkSamples(); + times.reserve( num_samples ); + for ( size_t i = 0; i < num_samples; ++i ) { Detail::ChronometerModel<Clock> model; - this->benchmark(Chronometer(model, iterations_per_sample)); + this->benchmark( Chronometer( model, iterations_per_sample ) ); auto sample_time = model.elapsed() - env.clock_cost.mean; - if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero(); - return sample_time / iterations_per_sample; - }); + if ( sample_time < FloatDuration<Clock>::zero() ) { + sample_time = FloatDuration<Clock>::zero(); + } + times.push_back(sample_time / iterations_per_sample); + } return times; } }; diff --git a/src/catch2/benchmark/catch_sample_analysis.hpp b/src/catch2/benchmark/catch_sample_analysis.hpp index d849d246..97b8fe50 100644 --- a/src/catch2/benchmark/catch_sample_analysis.hpp +++ b/src/catch2/benchmark/catch_sample_analysis.hpp @@ -10,14 +10,11 @@ #ifndef CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED #define CATCH_SAMPLE_ANALYSIS_HPP_INCLUDED -#include <catch2/benchmark/catch_clock.hpp> #include <catch2/benchmark/catch_estimate.hpp> #include <catch2/benchmark/catch_outlier_classification.hpp> #include <catch2/internal/catch_move_and_forward.hpp> -#include <algorithm> #include <vector> -#include <iterator> namespace Catch { namespace Benchmark { @@ -33,7 +30,9 @@ namespace Catch { operator SampleAnalysis<Duration2>() const { std::vector<Duration2> samples2; samples2.reserve(samples.size()); - std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); }); + for (auto const& d : samples) { + samples2.push_back(Duration2(d)); + } return { CATCH_MOVE(samples2), mean, diff --git a/src/catch2/benchmark/detail/catch_analyse.hpp b/src/catch2/benchmark/detail/catch_analyse.hpp index 1751543c..c932ff26 100644 --- a/src/catch2/benchmark/detail/catch_analyse.hpp +++ b/src/catch2/benchmark/detail/catch_analyse.hpp @@ -16,8 +16,6 @@ #include <catch2/interfaces/catch_interfaces_config.hpp> #include <catch2/internal/catch_move_and_forward.hpp> -#include <algorithm> -#include <iterator> #include <vector> namespace Catch { @@ -28,7 +26,9 @@ namespace Catch { if (!cfg.benchmarkNoAnalysis()) { std::vector<double> samples; samples.reserve(static_cast<size_t>(last - first)); - std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); }); + for (auto current = first; current != last; ++current) { + samples.push_back( current->count() ); + } auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end()); auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end()); @@ -43,7 +43,10 @@ namespace Catch { }; std::vector<Duration> samples2; samples2.reserve(samples.size()); - std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); }); + for (auto s : samples) { + samples2.push_back( Duration( s ) ); + } + return { CATCH_MOVE(samples2), wrap_estimate(analysis.mean), diff --git a/src/catch2/benchmark/detail/catch_estimate_clock.hpp b/src/catch2/benchmark/detail/catch_estimate_clock.hpp index fb65450e..1e916ae4 100644 --- a/src/catch2/benchmark/detail/catch_estimate_clock.hpp +++ b/src/catch2/benchmark/detail/catch_estimate_clock.hpp @@ -19,7 +19,6 @@ #include <catch2/internal/catch_unique_ptr.hpp> #include <algorithm> -#include <iterator> #include <vector> #include <cmath> @@ -30,13 +29,16 @@ namespace Catch { std::vector<double> resolution(int k) { std::vector<TimePoint<Clock>> times; times.reserve(static_cast<size_t>(k + 1)); - std::generate_n(std::back_inserter(times), k + 1, now<Clock>{}); + for ( int i = 0; i < k + 1; ++i ) { + times.push_back( Clock::now() ); + } std::vector<double> deltas; deltas.reserve(static_cast<size_t>(k)); - std::transform(std::next(times.begin()), times.end(), times.begin(), - std::back_inserter(deltas), - [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); }); + for ( size_t idx = 1; idx < times.size(); ++idx ) { + deltas.push_back( static_cast<double>( + ( times[idx] - times[idx - 1] ).count() ) ); + } return deltas; } @@ -84,9 +86,11 @@ namespace Catch { std::vector<double> times; int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed)); times.reserve(static_cast<size_t>(nsamples)); - std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] { - return static_cast<double>((time_clock(r.iterations) / r.iterations).count()); - }); + for ( int s = 0; s < nsamples; ++s ) { + times.push_back( static_cast<double>( + ( time_clock( r.iterations ) / r.iterations ) + .count() ) ); + } return { FloatDuration<Clock>(mean(times.begin(), times.end())), classify_outliers(times.begin(), times.end()), diff --git a/src/catch2/benchmark/detail/catch_stats.cpp b/src/catch2/benchmark/detail/catch_stats.cpp index c6c87be3..a7863224 100644 --- a/src/catch2/benchmark/detail/catch_stats.cpp +++ b/src/catch2/benchmark/detail/catch_stats.cpp @@ -13,7 +13,7 @@ #include <cassert> #include <cstddef> -#include <iterator> +#include <numeric> #include <random> @@ -35,12 +35,19 @@ using Catch::Benchmark::Detail::sample; sample out; out.reserve(resamples); - std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] { - std::vector<double> resampled; - resampled.reserve(n); - std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[static_cast<std::ptrdiff_t>(dist(rng))]; }); - return estimator(resampled.begin(), resampled.end()); - }); + // We allocate the vector outside the loop to avoid realloc per resample + std::vector<double> resampled; + resampled.reserve( n ); + for ( size_t i = 0; i < resamples; ++i ) { + resampled.clear(); + for ( size_t s = 0; s < n; ++s ) { + resampled.push_back( + first[static_cast<std::ptrdiff_t>( dist( rng ) )] ); + } + const auto estimate = + estimator( resampled.begin(), resampled.end() ); + out.push_back( estimate ); + } std::sort(out.begin(), out.end()); return out; } diff --git a/src/catch2/benchmark/detail/catch_stats.hpp b/src/catch2/benchmark/detail/catch_stats.hpp index b71c5842..62ca80f2 100644 --- a/src/catch2/benchmark/detail/catch_stats.hpp +++ b/src/catch2/benchmark/detail/catch_stats.hpp @@ -15,8 +15,6 @@ #include <algorithm> #include <vector> -#include <numeric> -#include <tuple> #include <cmath> namespace Catch { @@ -77,13 +75,13 @@ namespace Catch { sample jack = jackknife(estimator, first, last); double jack_mean = mean(jack.begin(), jack.end()); - double sum_squares, sum_cubes; - std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> { - auto d = jack_mean - x; - auto d2 = d * d; - auto d3 = d2 * d; - return { sqcb.first + d2, sqcb.second + d3 }; - }); + double sum_squares = 0, sum_cubes = 0; + for (double x : jack) { + auto difference = jack_mean - x; + auto square = difference * difference; + auto cube = square * difference; + sum_squares += square; sum_cubes += cube; + } double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5)); long n = static_cast<long>(resample.size()); |