Replace vector iterator args in benchmarks with ptr args

This commit is contained in:
Martin Hořeňovský 2023-08-31 22:04:54 +02:00
parent b4ffba5087
commit 9bba07cb87
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
5 changed files with 62 additions and 48 deletions

View File

@ -30,8 +30,13 @@ namespace Catch {
samples.push_back( current->count() ); samples.push_back( current->count() );
} }
auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end()); auto analysis = Catch::Benchmark::Detail::analyse_samples(
auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end()); cfg.benchmarkConfidenceInterval(),
cfg.benchmarkResamples(),
samples.data(),
samples.data() + samples.size() );
auto outliers = Catch::Benchmark::Detail::classify_outliers(
samples.data(), samples.data() + samples.size() );
auto wrap_estimate = [](Estimate<double> e) { auto wrap_estimate = [](Estimate<double> e) {
return Estimate<Duration> { return Estimate<Duration> {

View File

@ -63,8 +63,8 @@ namespace Catch {
auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>) auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)
.result; .result;
return { return {
FloatDuration<Clock>(mean(r.begin(), r.end())), FloatDuration<Clock>(mean(r.data(), r.data() + r.size())),
classify_outliers(r.begin(), r.end()), classify_outliers(r.data(), r.data() + r.size()),
}; };
} }
template <typename Clock> template <typename Clock>
@ -92,8 +92,8 @@ namespace Catch {
.count() ) ); .count() ) );
} }
return { return {
FloatDuration<Clock>(mean(times.begin(), times.end())), FloatDuration<Clock>(mean(times.data(), times.data() + times.size())),
classify_outliers(times.begin(), times.end()), classify_outliers(times.data(), times.data() + times.size()),
}; };
} }

View File

@ -30,8 +30,8 @@ namespace Catch {
static sample static sample
resample( URng& rng, resample( URng& rng,
unsigned int resamples, unsigned int resamples,
std::vector<double>::const_iterator first, double const* first,
std::vector<double>::const_iterator last, double const* last,
Estimator& estimator ) { Estimator& estimator ) {
auto n = static_cast<size_t>( last - first ); auto n = static_cast<size_t>( last - first );
std::uniform_int_distribution<decltype( n )> dist( 0, std::uniform_int_distribution<decltype( n )> dist( 0,
@ -51,7 +51,7 @@ namespace Catch {
dist( rng ) )] ); dist( rng ) )] );
} }
const auto estimate = const auto estimate =
estimator( resampled.begin(), resampled.end() ); estimator( resampled.data(), resampled.data() + resampled.size() );
out.push_back( estimate ); out.push_back( estimate );
} }
std::sort( out.begin(), out.end() ); std::sort( out.begin(), out.end() );
@ -168,8 +168,7 @@ namespace Catch {
} }
static double static double
standard_deviation( std::vector<double>::const_iterator first, standard_deviation( double const* first, double const* last ) {
std::vector<double>::const_iterator last ) {
auto m = Catch::Benchmark::Detail::mean( first, last ); auto m = Catch::Benchmark::Detail::mean( first, last );
double variance = double variance =
std::accumulate( first, std::accumulate( first,
@ -201,7 +200,10 @@ namespace Catch {
# pragma GCC diagnostic pop # pragma GCC diagnostic pop
#endif #endif
double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) { double weighted_average_quantile( int k,
int q,
double* first,
double* last ) {
auto count = last - first; auto count = last - first;
double idx = (count - 1) * k / static_cast<double>(q); double idx = (count - 1) * k / static_cast<double>(q);
int j = static_cast<int>(idx); int j = static_cast<int>(idx);
@ -217,12 +219,11 @@ namespace Catch {
} }
OutlierClassification OutlierClassification
classify_outliers( std::vector<double>::const_iterator first, classify_outliers( double const* first, double const* last ) {
std::vector<double>::const_iterator last ) {
std::vector<double> copy( first, last ); std::vector<double> copy( first, last );
auto q1 = weighted_average_quantile( 1, 4, copy.begin(), copy.end() ); auto q1 = weighted_average_quantile( 1, 4, copy.data(), copy.data() + copy.size() );
auto q3 = weighted_average_quantile( 3, 4, copy.begin(), copy.end() ); auto q3 = weighted_average_quantile( 3, 4, copy.data(), copy.data() + copy.size() );
auto iqr = q3 - q1; auto iqr = q3 - q1;
auto los = q1 - ( iqr * 3. ); auto los = q1 - ( iqr * 3. );
auto lom = q1 - ( iqr * 1.5 ); auto lom = q1 - ( iqr * 1.5 );
@ -246,8 +247,7 @@ namespace Catch {
return o; return o;
} }
double mean( std::vector<double>::const_iterator first, double mean( double const* first, double const* last ) {
std::vector<double>::const_iterator last ) {
auto count = last - first; auto count = last - first;
double sum = 0.; double sum = 0.;
while (first != last) { while (first != last) {
@ -280,8 +280,8 @@ namespace Catch {
bootstrap_analysis analyse_samples(double confidence_level, bootstrap_analysis analyse_samples(double confidence_level,
unsigned int n_resamples, unsigned int n_resamples,
std::vector<double>::iterator first, double* first,
std::vector<double>::iterator last) { double* last) {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
static std::random_device entropy; static std::random_device entropy;
@ -293,8 +293,7 @@ namespace Catch {
auto stddev = &standard_deviation; auto stddev = &standard_deviation;
#if defined(CATCH_CONFIG_USE_ASYNC) #if defined(CATCH_CONFIG_USE_ASYNC)
auto Estimate = [=](double(*f)(std::vector<double>::const_iterator, auto Estimate = [=](double(*f)(double const*, double const*)) {
std::vector<double>::const_iterator)) {
auto seed = entropy(); auto seed = entropy();
return std::async(std::launch::async, [=] { return std::async(std::launch::async, [=] {
std::mt19937 rng(seed); std::mt19937 rng(seed);
@ -309,8 +308,7 @@ namespace Catch {
auto mean_estimate = mean_future.get(); auto mean_estimate = mean_future.get();
auto stddev_estimate = stddev_future.get(); auto stddev_estimate = stddev_future.get();
#else #else
auto Estimate = [=](double(*f)(std::vector<double>::const_iterator, auto Estimate = [=](double(*f)(double const* , double const*)) {
std::vector<double>::const_iterator)) {
auto seed = entropy(); auto seed = entropy();
std::mt19937 rng(seed); std::mt19937 rng(seed);
auto resampled = resample(rng, n_resamples, first, last, f); auto resampled = resample(rng, n_resamples, first, last, f);

View File

@ -26,19 +26,20 @@ namespace Catch {
// to centralize warning suppression // to centralize warning suppression
bool directCompare( double lhs, double rhs ); bool directCompare( double lhs, double rhs );
double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last); double weighted_average_quantile( int k,
int q,
double* first,
double* last );
OutlierClassification OutlierClassification
classify_outliers( std::vector<double>::const_iterator first, classify_outliers( double const* first, double const* last );
std::vector<double>::const_iterator last );
double mean( std::vector<double>::const_iterator first, double mean( double const* first, double const* last );
std::vector<double>::const_iterator last );
template <typename Estimator> template <typename Estimator>
sample jackknife(Estimator&& estimator, sample jackknife(Estimator&& estimator,
std::vector<double>::iterator first, double* first,
std::vector<double>::iterator last) { double* last) {
auto n = static_cast<size_t>(last - first); auto n = static_cast<size_t>(last - first);
auto second = first; auto second = first;
++second; ++second;
@ -63,8 +64,8 @@ namespace Catch {
template <typename Estimator> template <typename Estimator>
Estimate<double> bootstrap( double confidence_level, Estimate<double> bootstrap( double confidence_level,
std::vector<double>::iterator first, double* first,
std::vector<double>::iterator last, double* last,
sample const& resample, sample const& resample,
Estimator&& estimator ) { Estimator&& estimator ) {
auto n_samples = last - first; auto n_samples = last - first;
@ -74,7 +75,7 @@ namespace Catch {
if (n_samples == 1) return { point, point, point, confidence_level }; if (n_samples == 1) return { point, point, point, confidence_level };
sample jack = jackknife(estimator, first, last); sample jack = jackknife(estimator, first, last);
double jack_mean = mean(jack.begin(), jack.end()); double jack_mean = mean(jack.data(), jack.data() + jack.size());
double sum_squares = 0, sum_cubes = 0; double sum_squares = 0, sum_cubes = 0;
for (double x : jack) { for (double x : jack) {
auto difference = jack_mean - x; auto difference = jack_mean - x;
@ -116,8 +117,8 @@ namespace Catch {
bootstrap_analysis analyse_samples(double confidence_level, bootstrap_analysis analyse_samples(double confidence_level,
unsigned int n_resamples, unsigned int n_resamples,
std::vector<double>::iterator first, double* first,
std::vector<double>::iterator last); double* last);
} // namespace Detail } // namespace Detail
} // namespace Benchmark } // namespace Benchmark
} // namespace Catch } // namespace Catch

View File

@ -156,8 +156,12 @@ TEST_CASE("uniform samples", "[benchmark]") {
std::vector<double> samples(100); std::vector<double> samples(100);
std::fill(samples.begin(), samples.end(), 23); std::fill(samples.begin(), samples.end(), 23);
using it = std::vector<double>::iterator; auto e = Catch::Benchmark::Detail::bootstrap(
auto e = Catch::Benchmark::Detail::bootstrap(0.95, samples.begin(), samples.end(), samples, [](it a, it b) { 0.95,
samples.data(),
samples.data() + samples.size(),
samples,
[]( double const* a, double const* b ) {
auto sum = std::accumulate(a, b, 0.); auto sum = std::accumulate(a, b, 0.);
return sum / (b - a); return sum / (b - a);
}); });
@ -198,7 +202,7 @@ TEST_CASE("normal_quantile", "[benchmark]") {
TEST_CASE("mean", "[benchmark]") { TEST_CASE("mean", "[benchmark]") {
std::vector<double> x{ 10., 20., 14., 16., 30., 24. }; std::vector<double> x{ 10., 20., 14., 16., 30., 24. };
auto m = Catch::Benchmark::Detail::mean(x.begin(), x.end()); auto m = Catch::Benchmark::Detail::mean(x.data(), x.data() + x.size());
REQUIRE(m == 19.); REQUIRE(m == 19.);
} }
@ -206,9 +210,9 @@ TEST_CASE("mean", "[benchmark]") {
TEST_CASE("weighted_average_quantile", "[benchmark]") { TEST_CASE("weighted_average_quantile", "[benchmark]") {
std::vector<double> x{ 10., 20., 14., 16., 30., 24. }; std::vector<double> x{ 10., 20., 14., 16., 30., 24. };
auto q1 = Catch::Benchmark::Detail::weighted_average_quantile(1, 4, x.begin(), x.end()); auto q1 = Catch::Benchmark::Detail::weighted_average_quantile(1, 4, x.data(), x.data() + x.size());
auto med = Catch::Benchmark::Detail::weighted_average_quantile(1, 2, x.begin(), x.end()); auto med = Catch::Benchmark::Detail::weighted_average_quantile(1, 2, x.data(), x.data() + x.size());
auto q3 = Catch::Benchmark::Detail::weighted_average_quantile(3, 4, x.begin(), x.end()); auto q3 = Catch::Benchmark::Detail::weighted_average_quantile(3, 4, x.data(), x.data() + x.size());
REQUIRE(q1 == 14.5); REQUIRE(q1 == 14.5);
REQUIRE(med == 18.); REQUIRE(med == 18.);
@ -227,7 +231,8 @@ TEST_CASE("classify_outliers", "[benchmark]") {
SECTION("none") { SECTION("none") {
std::vector<double> x{ 10., 20., 14., 16., 30., 24. }; std::vector<double> x{ 10., 20., 14., 16., 30., 24. };
auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end()); auto o = Catch::Benchmark::Detail::classify_outliers(
x.data(), x.data() + x.size() );
REQUIRE(o.samples_seen == static_cast<int>(x.size())); REQUIRE(o.samples_seen == static_cast<int>(x.size()));
require_outliers(o, 0, 0, 0, 0); require_outliers(o, 0, 0, 0, 0);
@ -235,7 +240,8 @@ TEST_CASE("classify_outliers", "[benchmark]") {
SECTION("low severe") { SECTION("low severe") {
std::vector<double> x{ -12., 20., 14., 16., 30., 24. }; std::vector<double> x{ -12., 20., 14., 16., 30., 24. };
auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end()); auto o = Catch::Benchmark::Detail::classify_outliers(
x.data(), x.data() + x.size() );
REQUIRE(o.samples_seen == static_cast<int>(x.size())); REQUIRE(o.samples_seen == static_cast<int>(x.size()));
require_outliers(o, 1, 0, 0, 0); require_outliers(o, 1, 0, 0, 0);
@ -243,7 +249,8 @@ TEST_CASE("classify_outliers", "[benchmark]") {
SECTION("low mild") { SECTION("low mild") {
std::vector<double> x{ 1., 20., 14., 16., 30., 24. }; std::vector<double> x{ 1., 20., 14., 16., 30., 24. };
auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end()); auto o = Catch::Benchmark::Detail::classify_outliers(
x.data(), x.data() + x.size() );
REQUIRE(o.samples_seen == static_cast<int>(x.size())); REQUIRE(o.samples_seen == static_cast<int>(x.size()));
require_outliers(o, 0, 1, 0, 0); require_outliers(o, 0, 1, 0, 0);
@ -251,7 +258,8 @@ TEST_CASE("classify_outliers", "[benchmark]") {
SECTION("high mild") { SECTION("high mild") {
std::vector<double> x{ 10., 20., 14., 16., 36., 24. }; std::vector<double> x{ 10., 20., 14., 16., 36., 24. };
auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end()); auto o = Catch::Benchmark::Detail::classify_outliers(
x.data(), x.data() + x.size() );
REQUIRE(o.samples_seen == static_cast<int>(x.size())); REQUIRE(o.samples_seen == static_cast<int>(x.size()));
require_outliers(o, 0, 0, 1, 0); require_outliers(o, 0, 0, 1, 0);
@ -259,7 +267,8 @@ TEST_CASE("classify_outliers", "[benchmark]") {
SECTION("high severe") { SECTION("high severe") {
std::vector<double> x{ 10., 20., 14., 16., 49., 24. }; std::vector<double> x{ 10., 20., 14., 16., 49., 24. };
auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end()); auto o = Catch::Benchmark::Detail::classify_outliers(
x.data(), x.data() + x.size() );
REQUIRE(o.samples_seen == static_cast<int>(x.size())); REQUIRE(o.samples_seen == static_cast<int>(x.size()));
require_outliers(o, 0, 0, 0, 1); require_outliers(o, 0, 0, 0, 1);
@ -267,7 +276,8 @@ TEST_CASE("classify_outliers", "[benchmark]") {
SECTION("mixed") { SECTION("mixed") {
std::vector<double> x{ -20., 20., 14., 16., 39., 24. }; std::vector<double> x{ -20., 20., 14., 16., 39., 24. };
auto o = Catch::Benchmark::Detail::classify_outliers(x.begin(), x.end()); auto o = Catch::Benchmark::Detail::classify_outliers(
x.data(), x.data() + x.size() );
REQUIRE(o.samples_seen == static_cast<int>(x.size())); REQUIRE(o.samples_seen == static_cast<int>(x.size()));
require_outliers(o, 1, 0, 1, 0); require_outliers(o, 1, 0, 1, 0);