reporter.h revision 5f9823bd92b2a24da06fac7b43f6658ec20cc901
14242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// Copyright 2015 Google Inc. All rights reserved. 24242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// 34242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// Licensed under the Apache License, Version 2.0 (the "License"); 44242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// you may not use this file except in compliance with the License. 54242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// You may obtain a copy of the License at 64242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// 74242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// http://www.apache.org/licenses/LICENSE-2.0 84242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// 94242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// Unless required by applicable law or agreed to in writing, software 104242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// distributed under the License is distributed on an "AS IS" BASIS, 114242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// See the License for the specific language governing permissions and 134242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// limitations under the License. 144242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier#ifndef BENCHMARK_REPORTER_H_ 154242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier#define BENCHMARK_REPORTER_H_ 164242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 174242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier#include <string> 184242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier#include <utility> 194242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier#include <vector> 204242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 218e72846da4bde9cdc8162ac99ce4168c65154f7dEric Fiselier#include "benchmark_api.h" // For forward declaration of BenchmarkReporter 22df904a1980b148139e566028dad27e3bea828afdEric Fiselier 234242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiseliernamespace benchmark { 244242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 250b4111c3b31db8806e0c3960c7f1f541b20cdb8bKai Wolftypedef std::pair<const char*,double> TimeUnitMultiplier; 260b4111c3b31db8806e0c3960c7f1f541b20cdb8bKai Wolf 274242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// Interface for custom benchmark result printers. 284242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// By default, benchmark reports are printed to stdout. However an application 294242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// can control the destination of the reports by calling 304242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// RunSpecifiedBenchmarks and passing it a custom reporter object. 314242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// The reporter object must implement the following interface. 324242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselierclass BenchmarkReporter { 334242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier public: 344242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier struct Context { 354242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier int num_cpus; 364242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier double mhz_per_cpu; 374242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier bool cpu_scaling_enabled; 384242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 394242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // The number of chars in the longest benchmark name. 404242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier size_t name_field_width; 414242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier }; 424242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 434242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier struct Run { 444242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier Run() : 454242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier iterations(1), 467c69b36078b5773fbd6b09b539a30400138607a7Kai Wolf time_unit(kNanosecond), 474242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier real_accumulated_time(0), 484242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier cpu_accumulated_time(0), 494242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier bytes_per_second(0), 504242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier items_per_second(0), 51b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael max_heapbytes_used(0), 522e5c397b4829503a5cb023ac67d2a1f13ebda3aaIsmael complexity(O_None), 53b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael arg1(0), 542e5c397b4829503a5cb023ac67d2a1f13ebda3aaIsmael arg2(0), 555f9823bd92b2a24da06fac7b43f6658ec20cc901Ismael report_big_o(false), 562e5c397b4829503a5cb023ac67d2a1f13ebda3aaIsmael report_rms(false) {} 574242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 584242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier std::string benchmark_name; 594242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier std::string report_label; // Empty if not set by benchmark. 602cf277b6f65d882cc8d3010fc1c91deb5edb32baJean-Louis Leroy int64_t iterations; 617c69b36078b5773fbd6b09b539a30400138607a7Kai Wolf TimeUnit time_unit; 624242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier double real_accumulated_time; 634242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier double cpu_accumulated_time; 644242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 654242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // Zero if not set by benchmark. 664242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier double bytes_per_second; 674242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier double items_per_second; 684242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 694242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // This is set to 0.0 if memory tracing is not enabled. 704242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier double max_heapbytes_used; 71b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael 72b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael // Keep track of arguments to compute asymptotic complexity 73b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael BigO complexity; 74b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael int arg1; 75b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael int arg2; 762e5c397b4829503a5cb023ac67d2a1f13ebda3aaIsmael 77290bd60289ef571875415cf82be805f9a446c6a9Ismael // Inform print function whether the current run is a complexity report 785f9823bd92b2a24da06fac7b43f6658ec20cc901Ismael bool report_big_o; 792e5c397b4829503a5cb023ac67d2a1f13ebda3aaIsmael bool report_rms; 804242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier }; 814242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 824242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // Called once for every suite of benchmarks run. 834242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // The parameter "context" contains information that the 844242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // reporter may wish to use when generating its report, for example the 854242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // platform under which the benchmarks are running. The benchmark run is 864242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // never started if this function returns false, allowing the reporter 874242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // to skip runs based on the context information. 8820f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier virtual bool ReportContext(const Context& context) = 0; 894242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 904242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // Called once for each group of benchmark runs, gives information about 914242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // cpu-time and heap memory usage during the benchmark run. 924242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // Note that all the grouped benchmark runs should refer to the same 934242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier // benchmark, thus have the same name. 9420f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier virtual void ReportRuns(const std::vector<Run>& report) = 0; 95b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael 968afbf0ed3801ad12c4066d10e9d25764181321f4Ismael // Called once at the last benchmark in a family of benchmarks, gives information 978afbf0ed3801ad12c4066d10e9d25764181321f4Ismael // about asymptotic complexity and RMS. 98b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael // Note that all the benchmark runs in a range should refer to the same benchmark, 99b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael // thus have the same name. 100b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael virtual void ReportComplexity(const std::vector<Run>& complexity_reports) = 0; 10120f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier 10220f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier // Called once and only once after ever group of benchmarks is run and 10320f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier // reported. 10420f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier virtual void Finalize(); 1054242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 1064242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier virtual ~BenchmarkReporter(); 1076429348e0d986315d95a0582eb8f57a6a4488ac1Eric Fiselierprotected: 1085f9823bd92b2a24da06fac7b43f6658ec20cc901Ismael static void ComputeStats(const std::vector<Run> & reports, Run* mean, Run* stddev); 1095f9823bd92b2a24da06fac7b43f6658ec20cc901Ismael static void ComputeBigO(const std::vector<Run> & reports, Run* bigO, Run* rms); 1100b4111c3b31db8806e0c3960c7f1f541b20cdb8bKai Wolf static TimeUnitMultiplier GetTimeUnitAndMultiplier(TimeUnit unit); 1112e5c397b4829503a5cb023ac67d2a1f13ebda3aaIsmael static std::string GetBigO(BigO complexity); 1124242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier}; 1134242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 1144242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// Simple reporter that outputs benchmark data to the console. This is the 1154242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier// default reporter used by RunSpecifiedBenchmarks(). 1164242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselierclass ConsoleReporter : public BenchmarkReporter { 1174242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier public: 11820f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier virtual bool ReportContext(const Context& context); 11920f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier virtual void ReportRuns(const std::vector<Run>& reports); 120b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael virtual void ReportComplexity(const std::vector<Run>& complexity_reports); 1217c69b36078b5773fbd6b09b539a30400138607a7Kai Wolf 1227c69b36078b5773fbd6b09b539a30400138607a7Kai Wolf protected: 12320f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier virtual void PrintRunData(const Run& report); 12420f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier 12520f1c0e2a8e692076dd7a5586f73ab8e2d726c12Eric Fiselier size_t name_field_width_; 1264242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier}; 1274242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier 128f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselierclass JSONReporter : public BenchmarkReporter { 129f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselierpublic: 130f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselier JSONReporter() : first_report_(true) {} 131f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselier virtual bool ReportContext(const Context& context); 132f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselier virtual void ReportRuns(const std::vector<Run>& reports); 133b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael virtual void ReportComplexity(const std::vector<Run>& complexity_reports); 134f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselier virtual void Finalize(); 135f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselier 136f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselierprivate: 137f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselier void PrintRunData(const Run& report); 138f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselier 139f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselier bool first_report_; 140f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselier}; 141f65da9d58165c6ab626d6a55b9d47968510c72aeEric Fiselier 14271c41cde57d7c741fca05b07585966129cf2ac5bDominic Hamonclass CSVReporter : public BenchmarkReporter { 14371c41cde57d7c741fca05b07585966129cf2ac5bDominic Hamonpublic: 14471c41cde57d7c741fca05b07585966129cf2ac5bDominic Hamon virtual bool ReportContext(const Context& context); 14571c41cde57d7c741fca05b07585966129cf2ac5bDominic Hamon virtual void ReportRuns(const std::vector<Run>& reports); 146b73dc22944cb933289bbdbf5bb6616dbfc50168fIsmael virtual void ReportComplexity(const std::vector<Run>& complexity_reports); 14771c41cde57d7c741fca05b07585966129cf2ac5bDominic Hamon 14871c41cde57d7c741fca05b07585966129cf2ac5bDominic Hamonprivate: 14971c41cde57d7c741fca05b07585966129cf2ac5bDominic Hamon void PrintRunData(const Run& report); 15071c41cde57d7c741fca05b07585966129cf2ac5bDominic Hamon}; 15171c41cde57d7c741fca05b07585966129cf2ac5bDominic Hamon 1524242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier} // end namespace benchmark 1534242f2f1d73d7800d95cfc2af0f3a3513dad2dc5Eric Fiselier#endif // BENCHMARK_REPORTER_H_ 154