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