diff --git a/src/benchmark.cc b/src/benchmark.cc index 5a8e023d..e06567b8 100644 --- a/src/benchmark.cc +++ b/src/benchmark.cc @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + #include "benchmark/benchmark.h" #include "benchmark/macros.h" #include "colorprint.h" @@ -258,11 +260,15 @@ void ComputeStats(const std::vector& reports, Stat1MinMax_d(it->max_heapbytes_used, it->iterations); } - // Get the data from the accumulator to BenchmarkRunData's. + // Get the data from the accumulator to BenchmarkRunData's. In the + // computations below we must multiply by the number of iterations since + // PrintRunData will divide by it. mean_data->benchmark_name = reports[0].benchmark_name + "_mean"; - mean_data->iterations = real_accumulated_time_stat.numSamples(); - mean_data->real_accumulated_time = real_accumulated_time_stat.sum(); - mean_data->cpu_accumulated_time = cpu_accumulated_time_stat.sum(); + mean_data->iterations = iterations_stat.Mean(); + mean_data->real_accumulated_time = real_accumulated_time_stat.Mean() * + mean_data->iterations; + mean_data->cpu_accumulated_time = cpu_accumulated_time_stat.Mean() * + mean_data->iterations; mean_data->bytes_per_second = bytes_per_second_stat.Mean(); mean_data->items_per_second = items_per_second_stat.Mean(); mean_data->max_heapbytes_used = max_heapbytes_used_stat.max(); @@ -278,9 +284,17 @@ void ComputeStats(const std::vector& reports, stddev_data->benchmark_name = reports[0].benchmark_name + "_stddev"; stddev_data->report_label = mean_data->report_label; - stddev_data->iterations = real_accumulated_time_stat.numSamples(); - // We multiply by the number of iterations since PrintRunData expects a total - // time. + stddev_data->iterations = iterations_stat.StdDev(); + // Ugly hack here! iterations_stat.StdDev() above may be 0 if all the + // repetitions have the same number of iterations. Blindly multiplying by 0 + // in the computation of real/cpu_accumulated_time below would lead to 0/0 in + // PrintRunData. To avoid this, we set the number of iterations to something + // negative here, and PrintRunData prints it as 0 (see the std::max there). + // Thus the stddev of both the number of iterations and the times are printed + // correctly. + if (stddev_data->iterations == 0) { + stddev_data->iterations = -1; + } stddev_data->real_accumulated_time = real_accumulated_time_stat.StdDev() * stddev_data->iterations; stddev_data->cpu_accumulated_time = cpu_accumulated_time_stat.StdDev() * @@ -473,7 +487,8 @@ void ConsoleReporter::PrintRunData(const BenchmarkReporter::Run& result) const { (static_cast(result.iterations)), (result.cpu_accumulated_time * 1e9) / (static_cast(result.iterations))); - ColorPrintf(COLOR_CYAN, "%10lld", result.iterations); + // See ComputeStats for why a negative value is printed as 0. + ColorPrintf(COLOR_CYAN, "%10lld", std::max(0LL, result.iterations)); ColorPrintf(COLOR_DEFAULT, "%*s %*s %s %s\n", 13, rate.c_str(), 18, items.c_str(),