1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #ifndef BENCHMARK_REPORTER_H_
15 #define BENCHMARK_REPORTER_H_
16 
17 #include <string>
18 #include <utility>
19 #include <vector>
20 
21 #include "benchmark_api.h" // For forward declaration of BenchmarkReporter
22 
23 namespace benchmark {
24 
25 // Interface for custom benchmark result printers.
26 // By default, benchmark reports are printed to stdout. However an application
27 // can control the destination of the reports by calling
28 // RunSpecifiedBenchmarks and passing it a custom reporter object.
29 // The reporter object must implement the following interface.
30 class BenchmarkReporter {
31  public:
32   struct Context {
33     int num_cpus;
34     double mhz_per_cpu;
35     bool cpu_scaling_enabled;
36 
37     // The number of chars in the longest benchmark name.
38     size_t name_field_width;
39   };
40 
41   struct Run {
RunRun42     Run() :
43       iterations(1),
44       real_accumulated_time(0),
45       cpu_accumulated_time(0),
46       bytes_per_second(0),
47       items_per_second(0),
48       max_heapbytes_used(0) {}
49 
50     std::string benchmark_name;
51     std::string report_label;  // Empty if not set by benchmark.
52     int64_t iterations;
53     double real_accumulated_time;
54     double cpu_accumulated_time;
55 
56     // Zero if not set by benchmark.
57     double bytes_per_second;
58     double items_per_second;
59 
60     // This is set to 0.0 if memory tracing is not enabled.
61     double max_heapbytes_used;
62   };
63 
64   // Called once for every suite of benchmarks run.
65   // The parameter "context" contains information that the
66   // reporter may wish to use when generating its report, for example the
67   // platform under which the benchmarks are running. The benchmark run is
68   // never started if this function returns false, allowing the reporter
69   // to skip runs based on the context information.
70   virtual bool ReportContext(const Context& context) = 0;
71 
72   // Called once for each group of benchmark runs, gives information about
73   // cpu-time and heap memory usage during the benchmark run.
74   // Note that all the grouped benchmark runs should refer to the same
75   // benchmark, thus have the same name.
76   virtual void ReportRuns(const std::vector<Run>& report) = 0;
77 
78   // Called once and only once after ever group of benchmarks is run and
79   // reported.
80   virtual void Finalize();
81 
82   virtual ~BenchmarkReporter();
83 protected:
84     static void ComputeStats(std::vector<Run> const& reports, Run* mean, Run* stddev);
85 };
86 
87 // Simple reporter that outputs benchmark data to the console. This is the
88 // default reporter used by RunSpecifiedBenchmarks().
89 class ConsoleReporter : public BenchmarkReporter {
90  public:
91   virtual bool ReportContext(const Context& context);
92   virtual void ReportRuns(const std::vector<Run>& reports);
93 protected:
94   virtual void PrintRunData(const Run& report);
95 
96   size_t name_field_width_;
97 };
98 
99 class JSONReporter : public BenchmarkReporter {
100 public:
JSONReporter()101   JSONReporter() : first_report_(true) {}
102   virtual bool ReportContext(const Context& context);
103   virtual void ReportRuns(const std::vector<Run>& reports);
104   virtual void Finalize();
105 
106 private:
107   void PrintRunData(const Run& report);
108 
109   bool first_report_;
110 };
111 
112 class CSVReporter : public BenchmarkReporter {
113 public:
114   virtual bool ReportContext(const Context& context);
115   virtual void ReportRuns(const std::vector<Run>& reports);
116 
117 private:
118   void PrintRunData(const Run& report);
119 };
120 
121 } // end namespace benchmark
122 #endif // BENCHMARK_REPORTER_H_
123