18 #include "benchmark/benchmark.h"
32 return [](
int n) ->
double {
return n; };
34 return [](
int n) ->
double {
return std::pow(n, 2); };
36 return [](
int n) ->
double {
return std::pow(n, 3); };
38 return [](
int n) {
return log2(n); };
40 return [](
int n) {
return n * log2(n); };
43 return [](
int) {
return 1.0; };
78 const std::vector<double>& time,
80 double sigma_gn = 0.0;
81 double sigma_gn_squared = 0.0;
82 double sigma_time = 0.0;
83 double sigma_time_gn = 0.0;
86 for (
size_t i = 0;
i <
n.size(); ++
i) {
87 double gn_i = fitting_curve(n[i]);
89 sigma_gn_squared += gn_i * gn_i;
90 sigma_time += time[
i];
91 sigma_time_gn += time[
i] * gn_i;
98 result.coef = sigma_time_gn / sigma_gn_squared;
102 for (
size_t i = 0;
i <
n.size(); ++
i) {
103 double fit =
result.coef * fitting_curve(n[i]);
104 rms += pow((time[i] - fit), 2);
108 double mean = sigma_time /
n.size();
109 result.rms = sqrt(rms /
n.size()) / mean;
122 const std::vector<double>& time,
const BigO complexity) {
130 if (complexity ==
oAuto) {
135 best_fit.complexity =
o1;
138 for (
const auto& fit : fit_curves) {
140 if (current_fit.rms < best_fit.rms) {
141 best_fit = current_fit;
142 best_fit.complexity = fit;
147 best_fit.complexity = complexity;
154 const std::vector<BenchmarkReporter::Run>& reports) {
159 std::count_if(reports.begin(), reports.end(),
160 [](
Run const&
run) { return run.error_occurred; });
162 if (reports.size() - error_count < 2) {
167 Stat1_d real_accumulated_time_stat;
168 Stat1_d cpu_accumulated_time_stat;
173 int64_t const run_iterations = reports.front().iterations;
179 std::map< std::string, CounterStat > counter_stats;
180 for(
Run const&
r : reports) {
181 for(
auto const& cnt :
r.counters) {
182 auto it = counter_stats.find(cnt.first);
183 if(
it == counter_stats.end()) {
184 counter_stats.insert({cnt.first, {cnt.second,
Stat1_d{}}});
186 CHECK_EQ(counter_stats[cnt.first].c.flags, cnt.second.flags);
192 for (
Run const&
run : reports) {
193 CHECK_EQ(reports[0].benchmark_name,
run.benchmark_name);
195 if (
run.error_occurred)
continue;
196 real_accumulated_time_stat +=
198 cpu_accumulated_time_stat +=
200 items_per_second_stat +=
Stat1_d(
run.items_per_second);
201 bytes_per_second_stat +=
Stat1_d(
run.bytes_per_second);
203 for(
auto const& cnt :
run.counters) {
204 auto it = counter_stats.find(cnt.first);
212 mean_data.benchmark_name = reports[0].benchmark_name +
"_mean";
213 mean_data.iterations = run_iterations;
214 mean_data.real_accumulated_time =
215 real_accumulated_time_stat.Mean() * run_iterations;
216 mean_data.cpu_accumulated_time =
217 cpu_accumulated_time_stat.Mean() * run_iterations;
218 mean_data.bytes_per_second = bytes_per_second_stat.Mean();
219 mean_data.items_per_second = items_per_second_stat.Mean();
220 mean_data.time_unit = reports[0].time_unit;
222 for(
auto const& kv : counter_stats) {
223 auto c = Counter(kv.second.s.Mean(), counter_stats[kv.first].c.flags);
224 mean_data.counters[kv.first] =
c;
228 mean_data.report_label = reports[0].report_label;
229 for (std::size_t i = 1;
i < reports.size();
i++) {
230 if (reports[i].report_label != reports[0].report_label) {
231 mean_data.report_label =
"";
237 stddev_data.benchmark_name = reports[0].benchmark_name +
"_stddev";
238 stddev_data.report_label = mean_data.report_label;
239 stddev_data.iterations = 0;
240 stddev_data.real_accumulated_time = real_accumulated_time_stat.StdDev();
241 stddev_data.cpu_accumulated_time = cpu_accumulated_time_stat.StdDev();
242 stddev_data.bytes_per_second = bytes_per_second_stat.StdDev();
243 stddev_data.items_per_second = items_per_second_stat.StdDev();
244 stddev_data.time_unit = reports[0].time_unit;
246 for(
auto const& kv : counter_stats) {
247 auto c = Counter(kv.second.s.StdDev(), counter_stats[kv.first].c.flags);
248 stddev_data.counters[kv.first] =
c;
252 results.push_back(stddev_data);
257 const std::vector<BenchmarkReporter::Run>& reports) {
261 if (reports.size() < 2)
return results;
265 std::vector<double> real_time;
266 std::vector<double> cpu_time;
269 for (
const Run&
run : reports) {
270 CHECK_GT(
run.complexity_n, 0) <<
"Did you forget to call SetComplexityN?";
271 n.push_back(
run.complexity_n);
272 real_time.push_back(
run.real_accumulated_time /
run.iterations);
273 cpu_time.push_back(
run.cpu_accumulated_time /
run.iterations);
279 if (reports[0].complexity ==
oLambda) {
280 result_cpu =
MinimalLeastSq(n, cpu_time, reports[0].complexity_lambda);
281 result_real =
MinimalLeastSq(n, real_time, reports[0].complexity_lambda);
284 result_real =
MinimalLeastSq(n, real_time, result_cpu.complexity);
287 reports[0].benchmark_name.substr(0, reports[0].benchmark_name.find(
'/'));
291 big_o.benchmark_name = benchmark_name +
"_BigO";
292 big_o.iterations = 0;
293 big_o.real_accumulated_time = result_real.coef;
294 big_o.cpu_accumulated_time = result_cpu.coef;
295 big_o.report_big_o =
true;
296 big_o.complexity = result_cpu.complexity;
307 big_o.report_label = reports[0].report_label;
308 rms.benchmark_name = benchmark_name +
"_RMS";
309 rms.report_label = big_o.report_label;
311 rms.real_accumulated_time = result_real.rms / multiplier;
312 rms.cpu_accumulated_time = result_cpu.rms / multiplier;
313 rms.report_rms =
true;
314 rms.complexity = result_cpu.complexity;
317 rms.time_unit = reports[0].time_unit;