summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/test/testsupport/perf_test_histogram_writer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/test/testsupport/perf_test_histogram_writer.cc')
-rw-r--r--third_party/libwebrtc/test/testsupport/perf_test_histogram_writer.cc201
1 files changed, 201 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/testsupport/perf_test_histogram_writer.cc b/third_party/libwebrtc/test/testsupport/perf_test_histogram_writer.cc
new file mode 100644
index 0000000000..93924ba16c
--- /dev/null
+++ b/third_party/libwebrtc/test/testsupport/perf_test_histogram_writer.cc
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "test/testsupport/perf_test_histogram_writer.h"
+
+#include <stdlib.h>
+
+#include <map>
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "api/numerics/samples_stats_counter.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/strings/string_builder.h"
+#include "rtc_base/synchronization/mutex.h"
+#include "third_party/catapult/tracing/tracing/value/diagnostics/reserved_infos.h"
+#include "third_party/catapult/tracing/tracing/value/histogram.h"
+
+namespace webrtc {
+namespace test {
+
+namespace {
+
+namespace proto = catapult::tracing::tracing::proto;
+
+std::string AsJsonString(const std::string string) {
+ return "\"" + string + "\"";
+}
+
+class PerfTestHistogramWriter : public PerfTestResultWriter {
+ public:
+ PerfTestHistogramWriter() : mutex_() {}
+ void ClearResults() override {
+ MutexLock lock(&mutex_);
+ histograms_.clear();
+ }
+
+ void LogResult(absl::string_view graph_name,
+ absl::string_view trace_name,
+ const double value,
+ absl::string_view units,
+ const bool important,
+ ImproveDirection improve_direction) override {
+ (void)important;
+ AddSample(graph_name, trace_name, value, units, improve_direction);
+ }
+ void LogResultMeanAndError(absl::string_view graph_name,
+ absl::string_view trace_name,
+ const double mean,
+ const double error,
+ absl::string_view units,
+ const bool important,
+ ImproveDirection improve_direction) override {
+ RTC_LOG(LS_WARNING) << "Discarding stddev, not supported by histograms";
+ (void)error;
+ (void)important;
+
+ AddSample(graph_name, trace_name, mean, units, improve_direction);
+ }
+ void LogResultList(absl::string_view graph_name,
+ absl::string_view trace_name,
+ const rtc::ArrayView<const double> values,
+ absl::string_view units,
+ const bool important,
+ ImproveDirection improve_direction) override {
+ (void)important;
+ for (double value : values) {
+ AddSample(graph_name, trace_name, value, units, improve_direction);
+ }
+ }
+ std::string Serialize() const override {
+ proto::HistogramSet histogram_set;
+
+ MutexLock lock(&mutex_);
+ for (const auto& histogram : histograms_) {
+ std::unique_ptr<proto::Histogram> proto = histogram.second->toProto();
+ histogram_set.mutable_histograms()->AddAllocated(proto.release());
+ }
+
+ std::string output;
+ bool ok = histogram_set.SerializeToString(&output);
+ RTC_DCHECK(ok) << "Failed to serialize histogram set to string";
+ return output;
+ }
+
+ private:
+ void AddSample(absl::string_view original_graph_name,
+ absl::string_view trace_name,
+ const double value,
+ absl::string_view units,
+ ImproveDirection improve_direction) {
+ // WebRTC annotates the units into the metric name when they are not
+ // supported by the Histogram API.
+ std::string graph_name(original_graph_name);
+ if (units == "dB") {
+ graph_name += "_dB";
+ } else if (units == "fps") {
+ graph_name += "_fps";
+ } else if (units == "%") {
+ graph_name += "_%";
+ }
+
+ // Lookup on graph name + trace name (or measurement + story in catapult
+ // parlance). There should be several histograms with the same measurement
+ // if they're for different stories.
+ rtc::StringBuilder measurement_and_story;
+ measurement_and_story << graph_name << trace_name;
+ MutexLock lock(&mutex_);
+ if (histograms_.count(measurement_and_story.str()) == 0) {
+ proto::UnitAndDirection unit = ParseUnit(units, improve_direction);
+ std::unique_ptr<catapult::HistogramBuilder> builder =
+ std::make_unique<catapult::HistogramBuilder>(graph_name, unit);
+
+ // Set all summary options as false - we don't want to generate
+ // metric_std, metric_count, and so on for all metrics.
+ builder->SetSummaryOptions(proto::SummaryOptions());
+ histograms_[measurement_and_story.str()] = std::move(builder);
+
+ proto::Diagnostic stories;
+ proto::GenericSet* generic_set = stories.mutable_generic_set();
+ generic_set->add_values(AsJsonString(std::string(trace_name)));
+ histograms_[measurement_and_story.str()]->AddDiagnostic(
+ catapult::kStoriesDiagnostic, stories);
+ }
+
+ if (units == "bps") {
+ // Bps has been interpreted as bits per second in WebRTC tests.
+ histograms_[measurement_and_story.str()]->AddSample(value / 8);
+ } else {
+ histograms_[measurement_and_story.str()]->AddSample(value);
+ }
+ }
+
+ proto::UnitAndDirection ParseUnit(absl::string_view units,
+ ImproveDirection improve_direction) {
+ RTC_DCHECK(units.find('_') == std::string::npos)
+ << "The unit_bigger|smallerIsBetter syntax isn't supported in WebRTC, "
+ "use the enum instead.";
+
+ proto::UnitAndDirection result;
+ result.set_improvement_direction(ParseDirection(improve_direction));
+ if (units == "bps") {
+ result.set_unit(proto::BYTES_PER_SECOND);
+ } else if (units == "dB") {
+ result.set_unit(proto::UNITLESS);
+ } else if (units == "fps") {
+ result.set_unit(proto::HERTZ);
+ } else if (units == "frames") {
+ result.set_unit(proto::COUNT);
+ } else if (units == "ms") {
+ result.set_unit(proto::MS_BEST_FIT_FORMAT);
+ } else if (units == "%") {
+ result.set_unit(proto::UNITLESS);
+ } else {
+ proto::Unit unit = catapult::UnitFromJsonUnit(std::string(units));
+
+ // UnitFromJsonUnit returns UNITLESS if it doesn't recognize the unit.
+ if (unit == proto::UNITLESS && units != "unitless") {
+ RTC_LOG(LS_WARNING) << "Unit " << units << " is unsupported.";
+ }
+
+ result.set_unit(unit);
+ }
+ return result;
+ }
+
+ proto::ImprovementDirection ParseDirection(
+ ImproveDirection improve_direction) {
+ switch (improve_direction) {
+ case ImproveDirection::kNone:
+ return proto::NOT_SPECIFIED;
+ case ImproveDirection::kSmallerIsBetter:
+ return proto::SMALLER_IS_BETTER;
+ case ImproveDirection::kBiggerIsBetter:
+ return proto::BIGGER_IS_BETTER;
+ default:
+ RTC_DCHECK_NOTREACHED() << "Invalid enum value " << improve_direction;
+ }
+ }
+
+ private:
+ mutable Mutex mutex_;
+ std::map<std::string, std::unique_ptr<catapult::HistogramBuilder>> histograms_
+ RTC_GUARDED_BY(&mutex_);
+};
+
+} // namespace
+
+PerfTestResultWriter* CreateHistogramWriter() {
+ return new PerfTestHistogramWriter();
+}
+
+} // namespace test
+} // namespace webrtc