CppBenchmark 1.0.5.0
C++ Benchmark Library
Loading...
Searching...
No Matches
reporter_console.cpp
Go to the documentation of this file.
1
10
11#include "benchmark/console.h"
13#include "benchmark/version.h"
14
15#include <set>
16#include <sstream>
17
18namespace CppBenchmark {
19
21{
22 _stream << Color::DARKGREY << GenerateSeparator('=') << std::endl;
23 _stream << Color::WHITE << "CppBenchmark report. Version " << version << std::endl;
24}
25
27{
28 _stream << Color::DARKGREY << GenerateSeparator('=') << std::endl;
29 _stream << Color::WHITE << "CPU architecture: " << Color::LIGHTCYAN << System::CpuArchitecture() << std::endl;
30 _stream << Color::WHITE << "CPU logical cores: " << Color::LIGHTGREEN << System::CpuLogicalCores() << std::endl;
31 _stream << Color::WHITE << "CPU physical cores: " << Color::LIGHTGREEN << System::CpuPhysicalCores() << std::endl;
32 _stream << Color::WHITE << "CPU clock speed: " << Color::LIGHTGREEN << GenerateClockSpeed(System::CpuClockSpeed()) << std::endl;
33 _stream << Color::WHITE << "CPU Hyper-Threading: " << Color::LIGHTGREEN << (System::CpuHyperThreading() ? "enabled" : "disabled") << std::endl;
34 _stream << Color::WHITE << "RAM total: " << Color::YELLOW << GenerateDataSize(System::RamTotal()) << std::endl;
35 _stream << Color::WHITE << "RAM free: " << Color::YELLOW << GenerateDataSize(System::RamFree()) << std::endl;
36}
37
39{
40 _stream << Color::DARKGREY << GenerateSeparator('=') << std::endl;
41 _stream << Color::WHITE << "OS version: " << Color::DARKGREY << Environment::OSVersion() << std::endl;
42 _stream << Color::WHITE << "OS bits: " << Color::DARKGREY << (Environment::Is64BitOS() ? "64-bit" : (Environment::Is32BitOS() ? "32-bit" : "<unknown>")) << std::endl;
43 _stream << Color::WHITE << "Process bits: " << Color::DARKGREY << (Environment::Is64BitProcess() ? "64-bit" : (Environment::Is32BitProcess() ? "32-bit" : "<unknown>")) << std::endl;
44 _stream << Color::WHITE << "Process configuration: " << Color::DARKGREY << (Environment::IsDebug() ? "debug" : (Environment::IsRelease() ? "release" : "<unknown>")) << std::endl;
45 time_t timestamp = Environment::Timestamp();
46 _stream << Color::WHITE << "Local timestamp: " << Color::DARKGREY << std::asctime(std::localtime(&timestamp));
47 _stream << Color::WHITE << "UTC timestamp: " << Color::DARKGREY << std::asctime(std::gmtime(&timestamp));
48}
49
50void ReporterConsole::ReportBenchmark(const BenchmarkBase& benchmark, const Settings& settings)
51{
52 _stream << Color::DARKGREY << GenerateSeparator('=') << std::endl;
53 _stream << Color::WHITE << "Benchmark: " << Color::LIGHTCYAN << benchmark.name() << std::endl;
54 _stream << Color::WHITE << "Attempts: " << Color::DARKGREY << settings.attempts() << std::endl;
55 if (settings.duration() > 0)
56 _stream << Color::WHITE << "Duration: " << Color::DARKGREY << settings.duration() << " seconds" << std::endl;
57 if (settings.operations() > 0)
58 _stream << Color::WHITE << "Operations: " << Color::DARKGREY << settings.operations() << std::endl;
59}
60
61void ReporterConsole::ReportPhase(const PhaseCore& phase, const PhaseMetrics& metrics)
62{
63 _stream << Color::DARKGREY << GenerateSeparator('-') << std::endl;
64 _stream << Color::WHITE << "Phase: " << Color::LIGHTCYAN << phase.name() << std::endl;
65 if (metrics.total_operations() > 1)
66 {
67 if (metrics.latency())
68 {
69 _stream << Color::WHITE << "Latency (Min): " << Color::YELLOW << GenerateTimePeriod(metrics.min_latency()) << "/op" << std::endl;
70 _stream << Color::WHITE << "Latency (Max): " << Color::YELLOW << GenerateTimePeriod(metrics.max_latency()) << "/op" << std::endl;
71 _stream << Color::WHITE << "Latency (Mean): " << Color::YELLOW << metrics.mean_latency() << std::endl;
72 _stream << Color::WHITE << "Latency (StDv): " << Color::YELLOW << metrics.stdv_latency() << std::endl;
73 }
74 else
75 {
76 _stream << Color::WHITE << "Average time: " << Color::YELLOW << GenerateTimePeriod(metrics.avg_time()) << "/op" << std::endl;
77 _stream << Color::WHITE << "Minimal time: " << Color::YELLOW << GenerateTimePeriod(metrics.min_time()) << "/op" << std::endl;
78 _stream << Color::WHITE << "Maximal time: " << Color::YELLOW << GenerateTimePeriod(metrics.max_time()) << "/op" << std::endl;
79 }
80 }
81 _stream << Color::WHITE << "Total time: " << Color::LIGHTRED << GenerateTimePeriod(metrics.total_time()) << std::endl;
82 if (metrics.total_operations() > 1)
83 _stream << Color::WHITE << "Total operations: " << Color::LIGHTGREEN << metrics.total_operations() << std::endl;
84 if (metrics.total_items() > 0)
85 _stream << Color::WHITE << "Total items: " << Color::LIGHTMAGENTA << metrics.total_items() << std::endl;
86 if (metrics.total_bytes() > 0)
87 _stream << Color::WHITE << "Total bytes: " << Color::MAGENTA << GenerateDataSize(metrics.total_bytes()) << std::endl;
88 if (metrics.total_operations() > 1)
89 _stream << Color::WHITE << "Operations throughput: " << Color::LIGHTGREEN << metrics.operations_per_second() << " ops/s" << std::endl;
90 if (metrics.total_items() > 0)
91 _stream << Color::WHITE << "Items throughput: " << Color::LIGHTMAGENTA << metrics.items_per_second() << " items/s" << std::endl;
92 if (metrics.total_bytes() > 0)
93 _stream << Color::WHITE << "Bytes throughput: " << Color::MAGENTA << GenerateDataSize(metrics.bytes_per_second()) << "/s" << std::endl;
94 if ((metrics.custom_int().size() > 0) || (metrics.custom_uint().size() > 0) ||
95 (metrics.custom_int64().size() > 0) || (metrics.custom_uint64().size() > 0) ||
96 (metrics.custom_flt().size() > 0) || (metrics.custom_dbl().size() > 0) ||
97 (metrics.custom_str().size() > 0))
98 {
99 _stream << Color::WHITE << "Custom values: " << std::endl;
100 std::set<std::string> names;
101 for (const auto& it : metrics.custom_int())
102 names.insert(it.first);
103 for (const auto& it : metrics.custom_uint())
104 names.insert(it.first);
105 for (const auto& it : metrics.custom_int64())
106 names.insert(it.first);
107 for (const auto& it : metrics.custom_uint64())
108 names.insert(it.first);
109 for (const auto& it : metrics.custom_flt())
110 names.insert(it.first);
111 for (const auto& it : metrics.custom_dbl())
112 names.insert(it.first);
113 for (const auto& it : metrics.custom_str())
114 names.insert(it.first);
115 for (const auto& name : names)
116 {
117 auto it_int = metrics.custom_int().find(name);
118 if (it_int != metrics.custom_int().end())
119 _stream << Color::DARKGREY << '\t' << it_int->first << ": " << Color::GREY << it_int->second << std::endl;
120 auto it_uint = metrics.custom_uint().find(name);
121 if (it_uint != metrics.custom_uint().end())
122 _stream << Color::DARKGREY << '\t' << it_uint->first << ": " << Color::GREY << it_uint->second << std::endl;
123 auto it_int64 = metrics.custom_int64().find(name);
124 if (it_int64 != metrics.custom_int64().end())
125 _stream << Color::DARKGREY << '\t' << it_int64->first << ": " << Color::GREY << it_int64->second << std::endl;
126 auto it_uint64 = metrics.custom_uint64().find(name);
127 if (it_uint64 != metrics.custom_uint64().end())
128 _stream << Color::DARKGREY << '\t' << it_uint64->first << ": " << Color::GREY << it_uint64->second << std::endl;
129 auto it_flt = metrics.custom_flt().find(name);
130 if (it_flt != metrics.custom_flt().end())
131 _stream << Color::DARKGREY << '\t' << it_flt->first << ": " << Color::GREY << it_flt->second << std::endl;
132 auto it_dbl = metrics.custom_dbl().find(name);
133 if (it_dbl != metrics.custom_dbl().end())
134 _stream << Color::DARKGREY << '\t' << it_dbl->first << ": " << Color::GREY << it_dbl->second << std::endl;
135 auto it_str = metrics.custom_str().find(name);
136 if (it_str != metrics.custom_str().end())
137 _stream << Color::DARKGREY << '\t' << it_str->first << ": " << Color::GREY << it_str->second << std::endl;
138 }
139 }
140}
141
143{
144 _stream << Color::DARKGREY << GenerateSeparator('=') << std::endl;
145}
146
148{
149 return std::string(79, ch);
150}
151
152std::string ReporterConsole::GenerateClockSpeed(int64_t hertz)
153{
154 std::ostringstream stream;
155
156 int64_t abs_hertz = std::abs(hertz);
157
158 if (abs_hertz >= 1000000000)
159 {
160 int64_t gigahertz = hertz / 1000000000;
161 int64_t megahertz = (hertz % 1000000000) / 1000000;
162 stream << gigahertz << '.' << ((megahertz < 100) ? "0" : "") << ((megahertz < 10) ? "0" : "") << megahertz << " GHz";
163 }
164 else if (abs_hertz >= 1000000)
165 {
166 int64_t megahertz = hertz / 1000000;
167 int64_t kilohertz = (hertz % 1000000) / 1000;
168 stream << megahertz << '.' << ((kilohertz < 100) ? "0" : "") << ((kilohertz < 10) ? "0" : "") << kilohertz << " MHz";
169 }
170 else if (abs_hertz >= 1000)
171 {
172 int64_t kilohertz = hertz / 1000;
173 hertz = hertz % 1000;
174 stream << kilohertz << '.' << ((hertz < 100) ? "0" : "") << ((hertz < 10) ? "0" : "") << hertz << " kHz";
175 }
176 else
177 stream << hertz << " Hz";
178
179 return stream.str();
180}
181
182std::string ReporterConsole::GenerateDataSize(int64_t bytes)
183{
184 std::ostringstream stream;
185
186 int64_t abs_bytes = std::abs(bytes);
187
188 if (abs_bytes >= (1024ll * 1024ll * 1024ll * 1024ll))
189 {
190 int64_t tb = bytes / (1024ll * 1024ll * 1024ll * 1024ll);
191 int64_t gb = (bytes % (1024ll * 1024ll * 1024ll * 1024ll)) / (1024 * 1024 * 1024);
192 stream << tb << '.' << ((gb < 100) ? "0" : "") << ((gb < 10) ? "0" : "") << gb << " TiB";
193 }
194 else if (abs_bytes >= (1024 * 1024 * 1024))
195 {
196 int64_t gb = bytes / (1024 * 1024 * 1024);
197 int64_t mb = (bytes % (1024 * 1024 * 1024)) / (1024 * 1024);
198 stream << gb << '.' << ((mb < 100) ? "0" : "") << ((mb < 10) ? "0" : "") << mb << " GiB";
199 }
200 else if (abs_bytes >= (1024 * 1024))
201 {
202 int64_t mb = bytes / (1024 * 1024);
203 int64_t kb = (bytes % (1024 * 1024)) / 1024;
204 stream << mb << '.' << ((kb < 100) ? "0" : "") << ((kb < 10) ? "0" : "") << kb << " MiB";
205 }
206 else if (abs_bytes >= 1024)
207 {
208 int64_t kb = bytes / 1024;
209 bytes = bytes % 1024;
210 stream << kb << '.' << ((bytes < 100) ? "0" : "") << ((bytes < 10) ? "0" : "") << bytes << " KiB";
211 }
212 else
213 stream << bytes << " bytes";
214
215 return stream.str();
216}
217
218std::string ReporterConsole::GenerateTimePeriod(int64_t nanoseconds)
219{
220 std::ostringstream stream;
221
222 int64_t abs_nanoseconds = std::abs(nanoseconds);
223
224 if (abs_nanoseconds >= (60 * 60 * 1000000000ll))
225 {
226 int64_t hours = nanoseconds / (60 * 60 * 1000000000ll);
227 int64_t minutes = ((nanoseconds % (60 * 60 * 1000000000ll)) / 1000000000) / 60;
228 int64_t seconds = ((nanoseconds % (60 * 60 * 1000000000ll)) / 1000000000) % 60;
229 int64_t milliseconds = ((nanoseconds % (60 * 60 * 1000000000ll)) % 1000000000) / 1000000;
230 stream << hours << ':' << ((minutes < 10) ? "0" : "") << minutes << ':' << ((seconds < 10) ? "0" : "") << seconds << '.' << ((milliseconds < 100) ? "0" : "") << ((milliseconds < 10) ? "0" : "") << milliseconds << " h";
231 }
232 else if (abs_nanoseconds >= (60 * 1000000000ll))
233 {
234 int64_t minutes = nanoseconds / (60 * 1000000000ll);
235 int64_t seconds = (nanoseconds % (60 * 1000000000ll)) / 1000000000;
236 int64_t milliseconds = ((nanoseconds % (60 * 1000000000ll)) % 1000000000) / 1000000;
237 stream << minutes << ':' << ((seconds < 10) ? "0" : "") << seconds << '.' << ((milliseconds < 100) ? "0" : "") << ((milliseconds < 10) ? "0" : "") << milliseconds << " m";
238 }
239 else if (abs_nanoseconds >= 1000000000)
240 {
241 int64_t seconds = nanoseconds / 1000000000;
242 int64_t milliseconds = (nanoseconds % 1000000000) / 1000000;
243 stream << seconds << '.' << ((milliseconds < 100) ? "0" : "") << ((milliseconds < 10) ? "0" : "") << milliseconds << " s";
244 }
245 else if (abs_nanoseconds >= 1000000)
246 {
247 int64_t milliseconds = nanoseconds / 1000000;
248 int64_t microseconds = (nanoseconds % 1000000) / 1000;
249 stream << milliseconds << '.' << ((microseconds < 100) ? "0" : "") << ((microseconds < 10) ? "0" : "") << microseconds << " ms";
250 }
251 else if (abs_nanoseconds >= 1000)
252 {
253 int64_t microseconds = nanoseconds / 1000;
254 nanoseconds = nanoseconds % 1000;
255 stream << microseconds << '.' << ((nanoseconds < 100) ? "0" : "") << ((nanoseconds < 10) ? "0" : "") << nanoseconds << " mcs";
256 }
257 else
258 stream << nanoseconds << " ns";
259
260 return stream.str();
261}
262
263} // namespace CppBenchmark
Benchmark base class.
const std::string & name() const
Get benchmark name.
static bool IsDebug()
Is compiled in debug mode?
static std::string OSVersion()
Get OS version string.
static bool IsRelease()
Is compiled in release mode?
static time_t Timestamp()
Get the current time in seconds.
static bool Is64BitProcess()
Is 64-bit running process?
static bool Is64BitOS()
Is 64-bit OS?
static bool Is32BitOS()
Is 32-bit OS?
static bool Is32BitProcess()
Is 32-bit running process?
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.
const std::map< std::string, double > & custom_dbl() const noexcept
Get custom doubles map.
const std::map< std::string, unsigned > & custom_uint() const noexcept
Get custom unsigned integers map.
int64_t total_bytes() const noexcept
Get total bytes processed in the phase.
double mean_latency() const noexcept
Get latency mean value of the phase execution.
int64_t total_time() const noexcept
Get total time of the phase execution.
const std::map< std::string, int > & custom_int() const noexcept
Get custom integers map.
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, std::string > & custom_str() const noexcept
Get custom strings map.
int64_t total_items() const noexcept
Get total items processed in the phase.
const std::map< std::string, uint64_t > & custom_uint64() const noexcept
Get custom unsigned integers 64-bit map.
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.
int64_t bytes_per_second() const noexcept
Get data throughput (bytes / second)
int64_t items_per_second() const noexcept
Get items throughput (items / second)
int64_t operations_per_second() const noexcept
Get operations throughput (operations / second)
const std::map< std::string, int64_t > & custom_int64() const noexcept
Get custom integers 64-bit map.
const std::map< std::string, float > & custom_flt() const noexcept
Get custom float map.
bool latency() const noexcept
Is metrics contains latency values?
int64_t total_operations() const noexcept
Get total operations made in the phase.
static std::string GenerateClockSpeed(int64_t hertz)
Generate clock speed string.
void ReportBenchmark(const BenchmarkBase &benchmark, const Settings &settings) override
Report current benchmark information.
static std::string GenerateSeparator(char ch)
Generate separator string.
void ReportEnvironment() override
Report environment information.
void ReportHeader() override
Report header.
void ReportPhase(const PhaseCore &phase, const PhaseMetrics &metrics) override
Report current phase information.
static std::string GenerateTimePeriod(int64_t nanoseconds)
Generate time period string.
void ReportSystem() override
Report system information.
void ReportFooter() override
Report footer.
static std::string GenerateDataSize(int64_t bytes)
Generate data size string.
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:178
static std::string CpuArchitecture()
CPU architecture string.
Definition system.cpp:129
static int64_t RamFree()
Free RAM in bytes.
Definition system.cpp:352
static int64_t CpuClockSpeed()
CPU clock speed in Hz.
Definition system.cpp:270
static bool CpuHyperThreading()
Is CPU Hyper-Threading enabled?
Definition system.cpp:320
static int64_t RamTotal()
Total RAM in bytes.
Definition system.cpp:326
static int CpuLogicalCores()
CPU logical cores count.
Definition system.cpp:173
Console management definition.
Environment management definition.
C++ Benchmark project definitions.
Definition barrier.h:15
const char version[]
Project version.
Definition version.h:35
@ LIGHTMAGENTA
Light magenta color.
@ LIGHTCYAN
Light cyan color.
@ GREY
Grey color.
@ DARKGREY
Dark grey color.
@ LIGHTRED
Light red color.
@ YELLOW
Yellow color.
@ LIGHTGREEN
Light green color.
@ WHITE
White color.
@ MAGENTA
Magenta color.
Console reporter definition.
Version definition.