Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorMartin Hořeňovský2023-04-10 15:03:29 +0200
committerMartin Hořeňovský2023-05-01 13:21:41 +0200
commitfe64c28925d31292516ba0a172870e7deb3baad6 (patch)
treed351b3a4f89a2ede0e5383c48072bf99c3b072dc /src
parent7d07efc92b626da9d03223a3b5cfd5f80b7cc377 (diff)
downloadcatch3-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.hpp18
-rw-r--r--src/catch2/benchmark/catch_sample_analysis.hpp7
-rw-r--r--src/catch2/benchmark/detail/catch_analyse.hpp11
-rw-r--r--src/catch2/benchmark/detail/catch_estimate_clock.hpp20
-rw-r--r--src/catch2/benchmark/detail/catch_stats.cpp21
-rw-r--r--src/catch2/benchmark/detail/catch_stats.hpp16
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());