diff --git a/test/testsupport/perf_test.cc b/test/testsupport/perf_test.cc index 07f5feea2e..f1df471ee5 100644 --- a/test/testsupport/perf_test.cc +++ b/test/testsupport/perf_test.cc @@ -40,6 +40,69 @@ struct PlottableCounter { std::string units; }; +class PlottableCounterPrinter { + public: + PlottableCounterPrinter() : output_(stdout) {} + + void SetOutput(FILE* output) { + rtc::CritScope lock(&crit_); + output_ = output; + } + + void AddCounter(const std::string& graph_name, + const std::string& trace_name, + const webrtc::SamplesStatsCounter& counter, + const std::string& units) { + rtc::CritScope lock(&crit_); + plottable_counters_.push_back({graph_name, trace_name, counter, units}); + } + + void Print(const std::vector& desired_graphs_raw) const { + std::set desired_graphs(desired_graphs_raw.begin(), + desired_graphs_raw.end()); + rtc::CritScope lock(&crit_); + for (auto& counter : plottable_counters_) { + if (!desired_graphs.empty()) { + auto it = desired_graphs.find(counter.graph_name); + if (it == desired_graphs.end()) { + continue; + } + } + + std::ostringstream value_stream; + value_stream.precision(8); + value_stream << R"({"graph_name":")" << counter.graph_name << R"(",)"; + value_stream << R"("trace_name":")" << counter.trace_name << R"(",)"; + value_stream << R"("units":")" << counter.units << R"(",)"; + if (!counter.counter.IsEmpty()) { + value_stream << R"("mean":)" << counter.counter.GetAverage() << ','; + value_stream << R"("std":)" << counter.counter.GetStandardDeviation() + << ','; + } + value_stream << R"("samples":[)"; + const char* sep = ""; + for (const auto& sample : counter.counter.GetTimedSamples()) { + value_stream << sep << R"({"time":)" << sample.time.us() << ',' + << R"("value":)" << sample.value << '}'; + sep = ","; + } + value_stream << "]}"; + + fprintf(output_, "PLOTTABLE_DATA: %s\n", value_stream.str().c_str()); + } + } + + private: + rtc::CriticalSection crit_; + std::vector plottable_counters_ RTC_GUARDED_BY(&crit_); + FILE* output_ RTC_GUARDED_BY(&crit_); +}; + +PlottableCounterPrinter& GetPlottableCounterPrinter() { + static PlottableCounterPrinter* printer_ = new PlottableCounterPrinter(); + return *printer_; +} + class PerfResultsLogger { public: PerfResultsLogger() : crit_(), output_(stdout), graphs_() {} @@ -51,20 +114,6 @@ class PerfResultsLogger { rtc::CritScope lock(&crit_); output_ = output; } - void LogResult(const std::string& graph_name, - const std::string& trace_name, - const webrtc::SamplesStatsCounter& counter, - const std::string& units, - const bool important, - webrtc::test::ImproveDirection improve_direction) { - LogResultMeanAndError( - graph_name, trace_name, counter.IsEmpty() ? 0 : counter.GetAverage(), - counter.IsEmpty() ? 0 : counter.GetStandardDeviation(), units, - important, improve_direction); - - rtc::CritScope lock(&crit_); - plottable_counters_.push_back({graph_name, trace_name, counter, units}); - } void LogResult(const std::string& graph_name, const std::string& trace_name, const double value, @@ -144,41 +193,6 @@ class PerfResultsLogger { graphs_[graph_name].push_back(json_stream.str()); } std::string ToJSON() const; - void PrintPlottableCounters( - const std::vector& desired_graphs_raw) const { - std::set desired_graphs(desired_graphs_raw.begin(), - desired_graphs_raw.end()); - rtc::CritScope lock(&crit_); - for (auto& counter : plottable_counters_) { - if (!desired_graphs.empty()) { - auto it = desired_graphs.find(counter.graph_name); - if (it == desired_graphs.end()) { - continue; - } - } - - std::ostringstream value_stream; - value_stream.precision(8); - value_stream << R"({"graph_name":")" << counter.graph_name << R"(",)"; - value_stream << R"("trace_name":")" << counter.trace_name << R"(",)"; - value_stream << R"("units":")" << counter.units << R"(",)"; - if (!counter.counter.IsEmpty()) { - value_stream << R"("mean":)" << counter.counter.GetAverage() << ','; - value_stream << R"("std":)" << counter.counter.GetStandardDeviation() - << ','; - } - value_stream << R"("samples":[)"; - const char* sep = ""; - for (const auto& sample : counter.counter.GetTimedSamples()) { - value_stream << sep << R"({"time":)" << sample.time.us() << ',' - << R"("value":)" << sample.value << '}'; - sep = ","; - } - value_stream << "]}"; - - fprintf(output_, "PLOTTABLE_DATA: %s\n", value_stream.str().c_str()); - } - } private: void LogResultsImpl(const std::string& graph_name, @@ -217,7 +231,6 @@ class PerfResultsLogger { FILE* output_ RTC_GUARDED_BY(&crit_); std::map> graphs_ RTC_GUARDED_BY(&crit_); - std::vector plottable_counters_ RTC_GUARDED_BY(&crit_); }; std::string PerfResultsLogger::ToJSON() const { @@ -254,6 +267,7 @@ void ClearPerfResults() { void SetPerfResultsOutput(FILE* output) { GetPerfResultsLogger().SetOutput(output); + GetPlottableCounterPrinter().SetOutput(output); } std::string GetPerfResultsJSON() { @@ -261,7 +275,7 @@ std::string GetPerfResultsJSON() { } void PrintPlottableResults(const std::vector& desired_graphs) { - GetPerfResultsLogger().PrintPlottableCounters(desired_graphs); + GetPlottableCounterPrinter().Print(desired_graphs); } void WritePerfResults(const std::string& output_path) { @@ -289,8 +303,13 @@ void PrintResult(const std::string& measurement, const std::string& units, const bool important, ImproveDirection improve_direction) { - GetPerfResultsLogger().LogResult(measurement + modifier, trace, counter, - units, important, improve_direction); + PrintResultMeanAndError( + measurement, modifier, trace, + counter.IsEmpty() ? 0 : counter.GetAverage(), + counter.IsEmpty() ? 0 : counter.GetStandardDeviation(), units, important, + improve_direction); + GetPlottableCounterPrinter().AddCounter(measurement + modifier, trace, + counter, units); } void PrintResultMeanAndError(const std::string& measurement,