aboutsummaryrefslogtreecommitdiff
path: root/src/json_reporter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/json_reporter.cc')
-rw-r--r--src/json_reporter.cc131
1 files changed, 98 insertions, 33 deletions
diff --git a/src/json_reporter.cc b/src/json_reporter.cc
index 959d245..6559dfd 100644
--- a/src/json_reporter.cc
+++ b/src/json_reporter.cc
@@ -12,9 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "benchmark/benchmark.h"
-#include "complexity.h"
-
#include <algorithm>
#include <cmath>
#include <cstdint>
@@ -25,41 +22,61 @@
#include <tuple>
#include <vector>
+#include "benchmark/benchmark.h"
+#include "complexity.h"
#include "string_util.h"
#include "timers.h"
namespace benchmark {
-
namespace {
-std::string StrEscape(const std::string & s) {
+std::string StrEscape(const std::string& s) {
std::string tmp;
tmp.reserve(s.size());
for (char c : s) {
switch (c) {
- case '\b': tmp += "\\b"; break;
- case '\f': tmp += "\\f"; break;
- case '\n': tmp += "\\n"; break;
- case '\r': tmp += "\\r"; break;
- case '\t': tmp += "\\t"; break;
- case '\\': tmp += "\\\\"; break;
- case '"' : tmp += "\\\""; break;
- default : tmp += c; break;
+ case '\b':
+ tmp += "\\b";
+ break;
+ case '\f':
+ tmp += "\\f";
+ break;
+ case '\n':
+ tmp += "\\n";
+ break;
+ case '\r':
+ tmp += "\\r";
+ break;
+ case '\t':
+ tmp += "\\t";
+ break;
+ case '\\':
+ tmp += "\\\\";
+ break;
+ case '"':
+ tmp += "\\\"";
+ break;
+ default:
+ tmp += c;
+ break;
}
}
return tmp;
}
std::string FormatKV(std::string const& key, std::string const& value) {
- return StrFormat("\"%s\": \"%s\"", StrEscape(key).c_str(), StrEscape(value).c_str());
+ return StrFormat("\"%s\": \"%s\"", StrEscape(key).c_str(),
+ StrEscape(value).c_str());
}
std::string FormatKV(std::string const& key, const char* value) {
- return StrFormat("\"%s\": \"%s\"", StrEscape(key).c_str(), StrEscape(value).c_str());
+ return StrFormat("\"%s\": \"%s\"", StrEscape(key).c_str(),
+ StrEscape(value).c_str());
}
std::string FormatKV(std::string const& key, bool value) {
- return StrFormat("\"%s\": %s", StrEscape(key).c_str(), value ? "true" : "false");
+ return StrFormat("\"%s\": %s", StrEscape(key).c_str(),
+ value ? "true" : "false");
}
std::string FormatKV(std::string const& key, int64_t value) {
@@ -68,12 +85,6 @@ std::string FormatKV(std::string const& key, int64_t value) {
return ss.str();
}
-std::string FormatKV(std::string const& key, IterationCount value) {
- std::stringstream ss;
- ss << '"' << StrEscape(key) << "\": " << value;
- return ss.str();
-}
-
std::string FormatKV(std::string const& key, double value) {
std::stringstream ss;
ss << '"' << StrEscape(key) << "\": ";
@@ -123,7 +134,9 @@ bool JSONReporter::ReportContext(const Context& context) {
RoundDouble(info.cycles_per_second / 1000000.0))
<< ",\n";
if (CPUInfo::Scaling::UNKNOWN != info.scaling) {
- out << indent << FormatKV("cpu_scaling_enabled", info.scaling == CPUInfo::Scaling::ENABLED ? true : false)
+ out << indent
+ << FormatKV("cpu_scaling_enabled",
+ info.scaling == CPUInfo::Scaling::ENABLED ? true : false)
<< ",\n";
}
@@ -136,8 +149,8 @@ bool JSONReporter::ReportContext(const Context& context) {
out << cache_indent << FormatKV("type", CI.type) << ",\n";
out << cache_indent << FormatKV("level", static_cast<int64_t>(CI.level))
<< ",\n";
- out << cache_indent
- << FormatKV("size", static_cast<int64_t>(CI.size)) << ",\n";
+ out << cache_indent << FormatKV("size", static_cast<int64_t>(CI.size))
+ << ",\n";
out << cache_indent
<< FormatKV("num_sharing", static_cast<int64_t>(CI.num_sharing))
<< "\n";
@@ -159,7 +172,19 @@ bool JSONReporter::ReportContext(const Context& context) {
#else
const char build_type[] = "debug";
#endif
- out << indent << FormatKV("library_build_type", build_type) << "\n";
+ out << indent << FormatKV("library_build_type", build_type);
+
+ std::map<std::string, std::string>* global_context =
+ internal::GetGlobalContext();
+
+ if (global_context != nullptr) {
+ for (const auto& kv : *global_context) {
+ out << ",\n";
+ out << indent << FormatKV(kv.first, kv.second);
+ }
+ }
+ out << "\n";
+
// Close context block and open the list of benchmarks.
out << inner_indent << "},\n";
out << inner_indent << "\"benchmarks\": [\n";
@@ -197,6 +222,10 @@ void JSONReporter::PrintRunData(Run const& run) {
std::string indent(6, ' ');
std::ostream& out = GetOutputStream();
out << indent << FormatKV("name", run.benchmark_name()) << ",\n";
+ out << indent << FormatKV("family_index", run.family_index) << ",\n";
+ out << indent
+ << FormatKV("per_family_instance_index", run.per_family_instance_index)
+ << ",\n";
out << indent << FormatKV("run_name", run.run_name.str()) << ",\n";
out << indent << FormatKV("run_type", [&run]() -> const char* {
switch (run.run_type) {
@@ -215,15 +244,36 @@ void JSONReporter::PrintRunData(Run const& run) {
out << indent << FormatKV("threads", run.threads) << ",\n";
if (run.run_type == BenchmarkReporter::Run::RT_Aggregate) {
out << indent << FormatKV("aggregate_name", run.aggregate_name) << ",\n";
+ out << indent << FormatKV("aggregate_unit", [&run]() -> const char* {
+ switch (run.aggregate_unit) {
+ case StatisticUnit::kTime:
+ return "time";
+ case StatisticUnit::kPercentage:
+ return "percentage";
+ }
+ BENCHMARK_UNREACHABLE();
+ }()) << ",\n";
}
- if (run.error_occurred) {
- out << indent << FormatKV("error_occurred", run.error_occurred) << ",\n";
- out << indent << FormatKV("error_message", run.error_message) << ",\n";
+ if (internal::SkippedWithError == run.skipped) {
+ out << indent << FormatKV("error_occurred", true) << ",\n";
+ out << indent << FormatKV("error_message", run.skip_message) << ",\n";
+ } else if (internal::SkippedWithMessage == run.skipped) {
+ out << indent << FormatKV("skipped", true) << ",\n";
+ out << indent << FormatKV("skip_message", run.skip_message) << ",\n";
}
if (!run.report_big_o && !run.report_rms) {
out << indent << FormatKV("iterations", run.iterations) << ",\n";
- out << indent << FormatKV("real_time", run.GetAdjustedRealTime()) << ",\n";
- out << indent << FormatKV("cpu_time", run.GetAdjustedCPUTime());
+ if (run.run_type != Run::RT_Aggregate ||
+ run.aggregate_unit == StatisticUnit::kTime) {
+ out << indent << FormatKV("real_time", run.GetAdjustedRealTime())
+ << ",\n";
+ out << indent << FormatKV("cpu_time", run.GetAdjustedCPUTime());
+ } else {
+ assert(run.aggregate_unit == StatisticUnit::kPercentage);
+ out << indent << FormatKV("real_time", run.real_accumulated_time)
+ << ",\n";
+ out << indent << FormatKV("cpu_time", run.cpu_accumulated_time);
+ }
out << ",\n"
<< indent << FormatKV("time_unit", GetTimeUnitString(run.time_unit));
} else if (run.report_big_o) {
@@ -241,9 +291,21 @@ void JSONReporter::PrintRunData(Run const& run) {
out << ",\n" << indent << FormatKV(c.first, c.second);
}
- if (run.has_memory_result) {
+ if (run.memory_result) {
+ const MemoryManager::Result memory_result = *run.memory_result;
out << ",\n" << indent << FormatKV("allocs_per_iter", run.allocs_per_iter);
- out << ",\n" << indent << FormatKV("max_bytes_used", run.max_bytes_used);
+ out << ",\n"
+ << indent << FormatKV("max_bytes_used", memory_result.max_bytes_used);
+
+ auto report_if_present = [&out, &indent](const std::string& label,
+ int64_t val) {
+ if (val != MemoryManager::TombstoneValue)
+ out << ",\n" << indent << FormatKV(label, val);
+ };
+
+ report_if_present("total_allocated_bytes",
+ memory_result.total_allocated_bytes);
+ report_if_present("net_heap_growth", memory_result.net_heap_growth);
}
if (!run.report_label.empty()) {
@@ -252,4 +314,7 @@ void JSONReporter::PrintRunData(Run const& run) {
out << '\n';
}
+const int64_t MemoryManager::TombstoneValue =
+ std::numeric_limits<int64_t>::max();
+
} // end namespace benchmark