16 #include "benchmark/benchmark.h"
33 if (
v.empty())
return 0.0;
39 std::vector<double>
copy(
v);
41 auto center =
copy.begin() +
v.size() / 2;
42 std::nth_element(
copy.begin(), center,
copy.end());
48 if (
v.size() % 2 == 1)
return *center;
49 auto center2 =
copy.begin() +
v.size() / 2 - 1;
50 std::nth_element(
copy.begin(), center2,
copy.end());
51 return (*center + *center2) / 2.0;
56 return std::inner_product(
v.begin(),
v.end(),
v.begin(), 0.0);
59 auto Sqr = [](
const double dat) {
return dat * dat; };
60 auto Sqrt = [](
const double dat) {
62 if (dat < 0.0)
return 0.0;
63 return std::sqrt(dat);
68 if (
v.empty())
return mean;
71 if (
v.size() == 1)
return 0.0;
73 const double avg_squares =
SumSquares(
v) * (1.0 /
v.size());
74 return Sqrt(
v.size() / (
v.size() - 1.0) * (avg_squares -
Sqr(mean)));
78 if (
v.size() < 2)
return 0.0;
87 const std::vector<BenchmarkReporter::Run>& reports) {
92 std::count_if(reports.begin(), reports.end(),
93 [](
Run const&
run) { return run.error_occurred; });
95 if (reports.size() - error_count < 2) {
101 std::vector<double> real_accumulated_time_stat;
102 std::vector<double> cpu_accumulated_time_stat;
104 real_accumulated_time_stat.reserve(reports.size());
105 cpu_accumulated_time_stat.reserve(reports.size());
113 std::vector<double> s;
115 std::map<std::string, CounterStat> counter_stats;
116 for (
Run const&
r : reports) {
117 for (
auto const& cnt :
r.counters) {
118 auto it = counter_stats.find(cnt.first);
119 if (
it == counter_stats.end()) {
120 counter_stats.insert({cnt.first, {cnt.second, std::vector<double>{}}});
121 it = counter_stats.find(cnt.first);
122 it->second.s.reserve(reports.size());
124 BM_CHECK_EQ(counter_stats[cnt.first].c.flags, cnt.second.flags);
130 for (
Run const&
run : reports) {
133 if (
run.error_occurred)
continue;
134 real_accumulated_time_stat.emplace_back(
run.real_accumulated_time);
135 cpu_accumulated_time_stat.emplace_back(
run.cpu_accumulated_time);
137 for (
auto const& cnt :
run.counters) {
138 auto it = counter_stats.find(cnt.first);
140 it->second.s.emplace_back(cnt.second);
145 std::string report_label = reports[0].report_label;
146 for (std::size_t
i = 1;
i < reports.size();
i++) {
147 if (reports[
i].report_label != report_label) {
153 const double iteration_rescale_factor =
154 double(reports.size()) / double(run_iterations);
156 for (
const auto&
Stat : *reports[0].statistics) {
159 data.run_name = reports[0].run_name;
160 data.family_index = reports[0].family_index;
161 data.per_family_instance_index = reports[0].per_family_instance_index;
163 data.threads = reports[0].threads;
164 data.repetitions = reports[0].repetitions;
165 data.repetition_index = Run::no_repetition_index;
168 data.report_label = report_label;
175 data.iterations = reports.size();
177 data.real_accumulated_time =
Stat.compute_(real_accumulated_time_stat);
178 data.cpu_accumulated_time =
Stat.compute_(cpu_accumulated_time_stat);
186 data.real_accumulated_time *= iteration_rescale_factor;
187 data.cpu_accumulated_time *= iteration_rescale_factor;
190 data.time_unit = reports[0].time_unit;
193 for (
auto const& kv : counter_stats) {
195 const auto uc_stat =
Stat.compute_(kv.second.s);
196 auto c =
Counter(uc_stat, counter_stats[kv.first].c.flags,
197 counter_stats[kv.first].c.oneK);
198 data.counters[kv.first] = c;