CppBenchmark  1.0.4.0
C++ Benchmark Library
reporter_json.cpp
Go to the documentation of this file.
1 
10 
11 #include "benchmark/environment.h"
12 #include "benchmark/version.h"
13 
14 #include <set>
15 
16 namespace CppBenchmark {
17 
19 namespace Internals {
20 
21 std::string indent1 = std::string(2, ' ');
22 std::string indent2 = std::string(4, ' ');
23 std::string indent3 = std::string(6, ' ');
24 std::string indent4 = std::string(8, ' ');
25 std::string indent5 = std::string(10, ' ');
26 std::string indent6 = std::string(12, ' ');
27 std::string indent7 = std::string(14, ' ');
28 std::string indent8 = std::string(16, ' ');
29 
30 } // namespace Internals
32 
34 {
35  _stream << "{\n";
36  _stream << Internals::indent1 << "\"version\": \"" << version << "\",\n";
37 }
38 
40 {
41  _stream << Internals::indent1 << "\"system\": {\n";
42  _stream << Internals::indent2 << "\"cpu_architecture\": \"" << System::CpuArchitecture() << "\",\n";
43  _stream << Internals::indent2 << "\"cpu_logical_cores\": " << System::CpuLogicalCores() << ",\n";
44  _stream << Internals::indent2 << "\"cpu_physical_cores\": " << System::CpuPhysicalCores() << ",\n";
45  _stream << Internals::indent2 << "\"cpu_clock_speed\": " << System::CpuClockSpeed() << ",\n";
46  _stream << Internals::indent2 << "\"cpu_hyper_threading\": " << (System::CpuHyperThreading() ? "true" : "false") << ",\n";
47  _stream << Internals::indent2 << "\"ram_total\": " << System::RamTotal() << ",\n";
48  _stream << Internals::indent2 << "\"ram_free\": " << System::RamFree() << "\n";
49  _stream << Internals::indent1 << "},\n";
50 }
51 
53 {
54  _stream << Internals::indent1 << "\"environment\": {\n";
55  _stream << Internals::indent2 << "\"is_64_bit_os\": " << (Environment::Is64BitOS() ? "true" : "false") << ",\n";
56  _stream << Internals::indent2 << "\"is_32_bit_os\": " << (Environment::Is32BitOS() ? "true" : "false") << ",\n";
57  _stream << Internals::indent2 << "\"is_64_bit_process\": " << (Environment::Is64BitProcess() ? "true" : "false") << ",\n";
58  _stream << Internals::indent2 << "\"is_32_bit_process\": " << (Environment::Is32BitProcess() ? "true" : "false") << ",\n";
59  _stream << Internals::indent2 << "\"is_debug\": " << (Environment::IsDebug() ? "true" : "false") << ",\n";
60  _stream << Internals::indent2 << "\"is_release\": " << (Environment::IsRelease() ? "true" : "false") << ",\n";
61  _stream << Internals::indent2 << "\"os_version\": \"" << Environment::OSVersion() << "\",\n";
62  _stream << Internals::indent2 << "\"timestamp\": " << Environment::Timestamp() << "\n";
63  _stream << Internals::indent1 << "},\n";
64 }
65 
67 {
68  _stream << Internals::indent1 << "\"benchmarks\": [\n";
69 
70  // Reset benchmark comma
71  _benchmark_comma = false;
72 }
73 
75 {
76  _stream << '\n';
77  _stream << Internals::indent1 << "]\n";
78 }
79 
81 {
82  if (_benchmark_comma)
83  _stream << ",\n";
84  _stream << Internals::indent2 << "{\n";
85  _stream << Internals::indent3 << "\"benchmark\": {\n";
86  _benchmark_comma = true;
87 }
88 
90 {
91  _stream << Internals::indent3 << "}\n";
92  _stream << Internals::indent2 << "}";
93 }
94 
95 void ReporterJSON::ReportBenchmark(const BenchmarkBase& benchmark, const Settings& settings)
96 {
97  _stream << Internals::indent4 << "\"name\": \"" << benchmark.name() << "\",\n";
98  _stream << Internals::indent4 << "\"attempts\": " << settings.attempts() << ",\n";
99  if (settings.duration() > 0)
100  _stream << Internals::indent4 << "\"duration\": " << settings.duration() << ",\n";
101  if (settings.operations() > 0)
102  _stream << Internals::indent4 << "\"operations\": " << settings.operations() << ",\n";
103 }
104 
106 {
107  _stream << Internals::indent4 << "\"phases\": [\n";
108 
109  // Reset phase comma
110  _phase_comma = false;
111 }
112 
114 {
115  _stream << '\n';
116  _stream << Internals::indent4 << "]\n";
117 }
118 
120 {
121  if (_phase_comma)
122  _stream << ",\n";
123  _stream << Internals::indent5 << "{\n";
124  _stream << Internals::indent6 << "\"phase\": {\n";
125  _phase_comma = true;
126 }
127 
129 {
130  _stream << Internals::indent6 << "}\n";
131  _stream << Internals::indent5 << "}";
132 }
133 
134 void ReporterJSON::ReportPhase(const PhaseCore& phase, const PhaseMetrics& metrics)
135 {
136  _stream << Internals::indent7 << "\"name\": \"" << phase.name() << "\",\n";
137  if (metrics.total_operations() > 1)
138  {
139  if (metrics.latency())
140  {
141  _stream << Internals::indent7 << "\"min_latency\": " << metrics.min_latency() << ",\n";
142  _stream << Internals::indent7 << "\"max_latency\": " << metrics.max_latency() << ",\n";
143  _stream << Internals::indent7 << "\"mean_latency\": " << metrics.mean_latency() << ",\n";
144  _stream << Internals::indent7 << "\"stdv_latency\": " << metrics.stdv_latency() << ",\n";
145  }
146  else
147  {
148  _stream << Internals::indent7 << "\"avg_time\": " << metrics.avg_time() << ",\n";
149  _stream << Internals::indent7 << "\"min_time\": " << metrics.min_time() << ",\n";
150  _stream << Internals::indent7 << "\"max_time\": " << metrics.max_time() << ",\n";
151  }
152  }
153  _stream << Internals::indent7 << "\"total_time\": " << metrics.total_time() << ",\n";
154  if (metrics.total_operations() > 1)
155  _stream << Internals::indent7 << "\"total_operations\": " << metrics.total_operations() << ",\n";
156  if (metrics.total_items() > 0)
157  _stream << Internals::indent7 << "\"total_items\": " << metrics.total_items() << ",\n";
158  if (metrics.total_bytes() > 0)
159  _stream << Internals::indent7 << "\"total_bytes\": " << metrics.total_bytes() << ",\n";
160  if (metrics.total_operations() > 1)
161  _stream << Internals::indent7 << "\"operations_per_second\": " << metrics.operations_per_second() << ",\n";
162  if (metrics.total_items() > 0)
163  _stream << Internals::indent7 << "\"items_per_second\": " << metrics.items_per_second() << ",\n";
164  if (metrics.total_bytes() > 0)
165  _stream << Internals::indent7 << "\"bytes_per_second\": " << metrics.bytes_per_second() << "\n";
166  _stream << Internals::indent7 << "\"custom\": [";
167  if (!metrics.custom_int().empty() || !metrics.custom_uint().empty() ||
168  !metrics.custom_int64().empty() || !metrics.custom_uint64().empty() ||
169  !metrics.custom_flt().empty() || !metrics.custom_dbl().empty() ||
170  !metrics.custom_str().empty())
171  {
172  std::set<std::string> names;
173  for (const auto& it : metrics.custom_int())
174  names.insert(it.first);
175  for (const auto& it : metrics.custom_uint())
176  names.insert(it.first);
177  for (const auto& it : metrics.custom_int64())
178  names.insert(it.first);
179  for (const auto& it : metrics.custom_uint64())
180  names.insert(it.first);
181  for (const auto& it : metrics.custom_flt())
182  names.insert(it.first);
183  for (const auto& it : metrics.custom_dbl())
184  names.insert(it.first);
185  for (const auto& it : metrics.custom_str())
186  names.insert(it.first);
187  bool comma = false;
188  for (const auto& name : names)
189  {
190  auto it_int = metrics.custom_int().find(name);
191  if (it_int != metrics.custom_int().end())
192  {
193  if (comma)
194  _stream << ',';
195  _stream << '\n' << Internals::indent8 << "{ " << '"' << it_int->first << "\": " << it_int->second << " }";
196  comma = true;
197  }
198  auto it_uint = metrics.custom_uint().find(name);
199  if (it_uint != metrics.custom_uint().end())
200  {
201  if (comma)
202  _stream << ',';
203  _stream << '\n' << Internals::indent8 << "{ " << '"' << it_uint->first << "\": " << it_uint->second << " }";
204  comma = true;
205  }
206  auto it_int64 = metrics.custom_int64().find(name);
207  if (it_int64 != metrics.custom_int64().end())
208  {
209  if (comma)
210  _stream << ',';
211  _stream << '\n' << Internals::indent8 << "{ " << '"' << it_int64->first << "\": " << it_int64->second << " }";
212  comma = true;
213  }
214  auto it_uint64 = metrics.custom_uint64().find(name);
215  if (it_uint64 != metrics.custom_uint64().end())
216  {
217  if (comma)
218  _stream << ',';
219  _stream << '\n' << Internals::indent8 << "{ " << '"' << it_uint64->first << "\": " << it_uint64->second << " }";
220  comma = true;
221  }
222  auto it_flt = metrics.custom_flt().find(name);
223  if (it_flt != metrics.custom_flt().end())
224  {
225  if (comma)
226  _stream << ',';
227  _stream << '\n' << Internals::indent8 << "{ " << '"' << it_flt->first << "\": " << it_flt->second << " }";
228  comma = true;
229  }
230  auto it_dbl = metrics.custom_dbl().find(name);
231  if (it_dbl != metrics.custom_dbl().end())
232  {
233  if (comma)
234  _stream << ',';
235  _stream << '\n' << Internals::indent8 << "{ " << '"' << it_dbl->first << "\": " << it_dbl->second << " }";
236  comma = true;
237  }
238  auto it_str = metrics.custom_str().find(name);
239  if (it_str != metrics.custom_str().end())
240  {
241  if (comma)
242  _stream << ',';
243  _stream << '\n' << Internals::indent8 << "{ " << '"' << it_str->first << "\": \"" << it_str->second << "\" }";
244  comma = true;
245  }
246  }
247  }
248  _stream << '\n';
249  _stream << Internals::indent7 << "]\n";
250 }
251 
253 {
254  _stream << "}\n";
255 }
256 
257 } // namespace CppBenchmark
Benchmark base class.
const std::string & name() const
Get benchmark name.
static bool IsDebug()
Is compiled in debug mode?
Definition: environment.cpp:81
static std::string OSVersion()
Get OS version string.
static bool IsRelease()
Is compiled in release mode?
Definition: environment.cpp:86
static time_t Timestamp()
Get the current time in seconds.
static bool Is64BitProcess()
Is 64-bit running process?
Definition: environment.cpp:62
static bool Is64BitOS()
Is 64-bit OS?
Definition: environment.cpp:38
static bool Is32BitOS()
Is 32-bit OS?
Definition: environment.cpp:33
static bool Is32BitProcess()
Is 32-bit running process?
Definition: environment.cpp:57
Benchmark phase core.
Definition: phase_core.h:27
const std::string & name() const noexcept override
Get phase name.
Definition: phase_core.h:53
Benchmark phase metrics.
Definition: phase_metrics.h:37
int64_t total_bytes() const noexcept
Get total bytes processed in the phase.
Definition: phase_metrics.h:75
double mean_latency() const noexcept
Get latency mean value of the phase execution.
const std::map< std::string, unsigned > & custom_uint() const noexcept
Get custom unsigned integers map.
Definition: phase_metrics.h:87
int64_t total_time() const noexcept
Get total time of the phase execution.
Definition: phase_metrics.h:69
int64_t min_time() const noexcept
Get minimal time of the phase execution.
int64_t min_latency() const noexcept
Get latency minimal value of the phase execution.
double stdv_latency() const noexcept
Get latency standard deviation of the phase execution.
int64_t max_latency() const noexcept
Get latency maximal value of the phase execution.
const std::map< std::string, int64_t > & custom_int64() const noexcept
Get custom integers 64-bit map.
Definition: phase_metrics.h:89
const std::map< std::string, std::string > & custom_str() const noexcept
Get custom strings map.
Definition: phase_metrics.h:97
int64_t total_items() const noexcept
Get total items processed in the phase.
Definition: phase_metrics.h:73
int64_t avg_time() const noexcept
Get average time of the phase execution.
int64_t max_time() const noexcept
Get maximal time of the phase execution.
const std::map< std::string, uint64_t > & custom_uint64() const noexcept
Get custom unsigned integers 64-bit map.
Definition: phase_metrics.h:91
int64_t bytes_per_second() const noexcept
Get data throughput (bytes / second)
int64_t items_per_second() const noexcept
Get items throughput (items / second)
const std::map< std::string, int > & custom_int() const noexcept
Get custom integers map.
Definition: phase_metrics.h:85
int64_t operations_per_second() const noexcept
Get operations throughput (operations / second)
const std::map< std::string, float > & custom_flt() const noexcept
Get custom float map.
Definition: phase_metrics.h:93
bool latency() const noexcept
Is metrics contains latency values?
const std::map< std::string, double > & custom_dbl() const noexcept
Get custom doubles map.
Definition: phase_metrics.h:95
int64_t total_operations() const noexcept
Get total operations made in the phase.
Definition: phase_metrics.h:71
void ReportBenchmarkHeader() override
Report current benchmark header.
void ReportBenchmark(const BenchmarkBase &benchmark, const Settings &settings) override
Report current benchmark information.
void ReportPhasesHeader() override
Report all phases header.
void ReportPhaseFooter() override
Report current phase footer.
void ReportBenchmarkFooter() override
Report current benchmark footer.
void ReportPhaseHeader() override
Report current phase header.
void ReportPhase(const PhaseCore &phase, const PhaseMetrics &metrics) override
Report current phase information.
void ReportHeader() override
Report header.
void ReportBenchmarksFooter() override
Report all benchmarks footer.
void ReportFooter() override
Report footer.
void ReportEnvironment() override
Report environment information.
void ReportSystem() override
Report system information.
void ReportPhasesFooter() override
Report all phases footer.
void ReportBenchmarksHeader() override
Report all benchmarks header.
Benchmark settings.
Definition: settings.h:32
int attempts() const noexcept
Get count of independent benchmark attempts.
Definition: settings.h:53
int64_t duration() const noexcept
Get benchmark duration in milliseconds.
Definition: settings.h:57
int64_t operations() const noexcept
Get count of operations.
Definition: settings.h:59
static int CpuPhysicalCores()
CPU physical cores count.
Definition: system.cpp:177
static std::string CpuArchitecture()
CPU architecture string.
Definition: system.cpp:128
static int64_t RamFree()
Free RAM in bytes.
Definition: system.cpp:331
static int64_t CpuClockSpeed()
CPU clock speed in Hz.
Definition: system.cpp:255
static bool CpuHyperThreading()
Is CPU Hyper-Threading enabled?
Definition: system.cpp:299
static int64_t RamTotal()
Total RAM in bytes.
Definition: system.cpp:305
static int CpuLogicalCores()
CPU logical cores count.
Definition: system.cpp:172
Environment management definition.
C++ Benchmark project definitions.
Definition: barrier.h:15
const char version[]
Project version.
Definition: version.h:35
JSON reporter definition.
Version definition.