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

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2
diff options
context:
space:
mode:
authorMartin Hořeňovský2023-04-20 22:47:21 +0200
committerMartin Hořeňovský2023-05-01 13:21:36 +0200
commit7d07efc92b626da9d03223a3b5cfd5f80b7cc377 (patch)
tree9d2ead9fad42293e5b362a8548346f5585795e88 /src/catch2
parentf3c678c0ab2afd5511d6ea4ff82ad3c5349312c0 (diff)
downloadcatch3-7d07efc92b626da9d03223a3b5cfd5f80b7cc377.tar.gz
Clean up iterator usage in benchmarks
Specifically we turned `mean`, `classify_outliers`, `jackknife`, into concrete functions that take only `const_iterator` from vecs, instead of generic iterators over anything. I also changed `resample` to take `const_iterator` instead of plain `iterator`, and similar for `standard_deviation`, and `analyse_samples`.
Diffstat (limited to 'src/catch2')
-rw-r--r--src/catch2/benchmark/detail/catch_stats.cpp62
-rw-r--r--src/catch2/benchmark/detail/catch_stats.hpp53
2 files changed, 75 insertions, 40 deletions
diff --git a/src/catch2/benchmark/detail/catch_stats.cpp b/src/catch2/benchmark/detail/catch_stats.cpp
index 514ed1f7..c6c87be3 100644
--- a/src/catch2/benchmark/detail/catch_stats.cpp
+++ b/src/catch2/benchmark/detail/catch_stats.cpp
@@ -26,7 +26,10 @@ namespace {
using Catch::Benchmark::Detail::sample;
template <typename URng, typename Estimator>
- sample resample(URng& rng, unsigned int resamples, std::vector<double>::iterator first, std::vector<double>::iterator last, Estimator& estimator) {
+ static sample resample(URng& rng, unsigned int resamples,
+ std::vector<double>::const_iterator first,
+ std::vector<double>::const_iterator last,
+ Estimator& estimator) {
auto n = static_cast<size_t>(last - first);
std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
@@ -118,7 +121,8 @@ using Catch::Benchmark::Detail::sample;
return p * x;
}
- double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {
+ double standard_deviation(std::vector<double>::const_iterator first,
+ std::vector<double>::const_iterator last) {
auto m = Catch::Benchmark::Detail::mean(first, last);
double variance = std::accumulate( first,
last,
@@ -161,6 +165,47 @@ namespace Catch {
return xj + g * (xj1 - xj);
}
+ OutlierClassification
+ classify_outliers( std::vector<double>::const_iterator first,
+ std::vector<double>::const_iterator last ) {
+ std::vector<double> copy( first, last );
+
+ auto q1 = weighted_average_quantile( 1, 4, copy.begin(), copy.end() );
+ auto q3 = weighted_average_quantile( 3, 4, copy.begin(), copy.end() );
+ auto iqr = q3 - q1;
+ auto los = q1 - ( iqr * 3. );
+ auto lom = q1 - ( iqr * 1.5 );
+ auto him = q3 + ( iqr * 1.5 );
+ auto his = q3 + ( iqr * 3. );
+
+ OutlierClassification o;
+ for ( ; first != last; ++first ) {
+ const double t = *first;
+ if ( t < los ) {
+ ++o.low_severe;
+ } else if ( t < lom ) {
+ ++o.low_mild;
+ } else if ( t > his ) {
+ ++o.high_severe;
+ } else if ( t > him ) {
+ ++o.high_mild;
+ }
+ ++o.samples_seen;
+ }
+ return o;
+ }
+
+ double mean( std::vector<double>::const_iterator first,
+ std::vector<double>::const_iterator last ) {
+ auto count = last - first;
+ double sum = 0.;
+ while (first != last) {
+ sum += *first;
+ ++first;
+ }
+ return sum / static_cast<double>(count);
+ }
+
double erfc_inv(double x) {
return erf_inv(1.0 - x);
@@ -210,7 +255,10 @@ namespace Catch {
}
- bootstrap_analysis analyse_samples(double confidence_level, unsigned int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
+ bootstrap_analysis analyse_samples(double confidence_level,
+ unsigned int n_resamples,
+ std::vector<double>::iterator first,
+ std::vector<double>::iterator last) {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
static std::random_device entropy;
@@ -218,11 +266,12 @@ namespace Catch {
auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
- auto mean = &Detail::mean<std::vector<double>::iterator>;
+ auto mean = &Detail::mean;
auto stddev = &standard_deviation;
#if defined(CATCH_CONFIG_USE_ASYNC)
- auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
+ auto Estimate = [=](double(*f)(std::vector<double>::const_iterator,
+ std::vector<double>::const_iterator)) {
auto seed = entropy();
return std::async(std::launch::async, [=] {
std::mt19937 rng(seed);
@@ -237,7 +286,8 @@ namespace Catch {
auto mean_estimate = mean_future.get();
auto stddev_estimate = stddev_future.get();
#else
- auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {
+ auto Estimate = [=](double(*f)(std::vector<double>::const_iterator,
+ std::vector<double>::const_iterator)) {
auto seed = entropy();
std::mt19937 rng(seed);
auto resampled = resample(rng, n_resamples, first, last, f);
diff --git a/src/catch2/benchmark/detail/catch_stats.hpp b/src/catch2/benchmark/detail/catch_stats.hpp
index 4c54ec52..b71c5842 100644
--- a/src/catch2/benchmark/detail/catch_stats.hpp
+++ b/src/catch2/benchmark/detail/catch_stats.hpp
@@ -30,39 +30,17 @@ namespace Catch {
double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
- template <typename Iterator>
- OutlierClassification classify_outliers(Iterator first, Iterator last) {
- std::vector<double> copy(first, last);
-
- auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
- auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
- auto iqr = q3 - q1;
- auto los = q1 - (iqr * 3.);
- auto lom = q1 - (iqr * 1.5);
- auto him = q3 + (iqr * 1.5);
- auto his = q3 + (iqr * 3.);
-
- OutlierClassification o;
- for (; first != last; ++first) {
- auto&& t = *first;
- if (t < los) ++o.low_severe;
- else if (t < lom) ++o.low_mild;
- else if (t > his) ++o.high_severe;
- else if (t > him) ++o.high_mild;
- ++o.samples_seen;
- }
- return o;
- }
+ OutlierClassification
+ classify_outliers( std::vector<double>::const_iterator first,
+ std::vector<double>::const_iterator last );
- template <typename Iterator>
- double mean(Iterator first, Iterator last) {
- auto count = last - first;
- double sum = std::accumulate(first, last, 0.);
- return sum / static_cast<double>(count);
- }
+ double mean( std::vector<double>::const_iterator first,
+ std::vector<double>::const_iterator last );
- template <typename Estimator, typename Iterator>
- sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
+ template <typename Estimator>
+ sample jackknife(Estimator&& estimator,
+ std::vector<double>::iterator first,
+ std::vector<double>::iterator last) {
auto n = static_cast<size_t>(last - first);
auto second = first;
++second;
@@ -85,8 +63,12 @@ namespace Catch {
double normal_quantile(double p);
- template <typename Iterator, typename Estimator>
- Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
+ template <typename Estimator>
+ Estimate<double> bootstrap( double confidence_level,
+ std::vector<double>::iterator first,
+ std::vector<double>::iterator last,
+ sample const& resample,
+ Estimator&& estimator ) {
auto n_samples = last - first;
double point = estimator(first, last);
@@ -136,7 +118,10 @@ namespace Catch {
double outlier_variance;
};
- bootstrap_analysis analyse_samples(double confidence_level, unsigned int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
+ bootstrap_analysis analyse_samples(double confidence_level,
+ unsigned int n_resamples,
+ std::vector<double>::iterator first,
+ std::vector<double>::iterator last);
} // namespace Detail
} // namespace Benchmark
} // namespace Catch