1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "test/testsupport/perf_test.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <stdio.h>
14*d9f75844SAndroid Build Coastguard Worker
15*d9f75844SAndroid Build Coastguard Worker #include <algorithm>
16*d9f75844SAndroid Build Coastguard Worker #include <fstream>
17*d9f75844SAndroid Build Coastguard Worker #include <set>
18*d9f75844SAndroid Build Coastguard Worker #include <sstream>
19*d9f75844SAndroid Build Coastguard Worker #include <vector>
20*d9f75844SAndroid Build Coastguard Worker
21*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/numerics/samples_stats_counter.h"
23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h"
26*d9f75844SAndroid Build Coastguard Worker #include "test/testsupport/file_utils.h"
27*d9f75844SAndroid Build Coastguard Worker #include "test/testsupport/perf_test_histogram_writer.h"
28*d9f75844SAndroid Build Coastguard Worker
29*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
30*d9f75844SAndroid Build Coastguard Worker namespace test {
31*d9f75844SAndroid Build Coastguard Worker
32*d9f75844SAndroid Build Coastguard Worker namespace {
33*d9f75844SAndroid Build Coastguard Worker
UnitWithDirection(absl::string_view units,webrtc::test::ImproveDirection improve_direction)34*d9f75844SAndroid Build Coastguard Worker std::string UnitWithDirection(
35*d9f75844SAndroid Build Coastguard Worker absl::string_view units,
36*d9f75844SAndroid Build Coastguard Worker webrtc::test::ImproveDirection improve_direction) {
37*d9f75844SAndroid Build Coastguard Worker switch (improve_direction) {
38*d9f75844SAndroid Build Coastguard Worker case webrtc::test::ImproveDirection::kNone:
39*d9f75844SAndroid Build Coastguard Worker return std::string(units);
40*d9f75844SAndroid Build Coastguard Worker case webrtc::test::ImproveDirection::kSmallerIsBetter:
41*d9f75844SAndroid Build Coastguard Worker return std::string(units) + "_smallerIsBetter";
42*d9f75844SAndroid Build Coastguard Worker case webrtc::test::ImproveDirection::kBiggerIsBetter:
43*d9f75844SAndroid Build Coastguard Worker return std::string(units) + "_biggerIsBetter";
44*d9f75844SAndroid Build Coastguard Worker }
45*d9f75844SAndroid Build Coastguard Worker }
46*d9f75844SAndroid Build Coastguard Worker
GetSortedSamples(const SamplesStatsCounter & counter)47*d9f75844SAndroid Build Coastguard Worker std::vector<SamplesStatsCounter::StatsSample> GetSortedSamples(
48*d9f75844SAndroid Build Coastguard Worker const SamplesStatsCounter& counter) {
49*d9f75844SAndroid Build Coastguard Worker rtc::ArrayView<const SamplesStatsCounter::StatsSample> view =
50*d9f75844SAndroid Build Coastguard Worker counter.GetTimedSamples();
51*d9f75844SAndroid Build Coastguard Worker std::vector<SamplesStatsCounter::StatsSample> out(view.begin(), view.end());
52*d9f75844SAndroid Build Coastguard Worker std::stable_sort(out.begin(), out.end(),
53*d9f75844SAndroid Build Coastguard Worker [](const SamplesStatsCounter::StatsSample& a,
54*d9f75844SAndroid Build Coastguard Worker const SamplesStatsCounter::StatsSample& b) {
55*d9f75844SAndroid Build Coastguard Worker return a.time < b.time;
56*d9f75844SAndroid Build Coastguard Worker });
57*d9f75844SAndroid Build Coastguard Worker return out;
58*d9f75844SAndroid Build Coastguard Worker }
59*d9f75844SAndroid Build Coastguard Worker
60*d9f75844SAndroid Build Coastguard Worker template <typename Container>
OutputListToStream(std::ostream * ostream,const Container & values)61*d9f75844SAndroid Build Coastguard Worker void OutputListToStream(std::ostream* ostream, const Container& values) {
62*d9f75844SAndroid Build Coastguard Worker const char* sep = "";
63*d9f75844SAndroid Build Coastguard Worker for (const auto& v : values) {
64*d9f75844SAndroid Build Coastguard Worker (*ostream) << sep << v;
65*d9f75844SAndroid Build Coastguard Worker sep = ",";
66*d9f75844SAndroid Build Coastguard Worker }
67*d9f75844SAndroid Build Coastguard Worker }
68*d9f75844SAndroid Build Coastguard Worker
69*d9f75844SAndroid Build Coastguard Worker struct PlottableCounter {
70*d9f75844SAndroid Build Coastguard Worker std::string graph_name;
71*d9f75844SAndroid Build Coastguard Worker std::string trace_name;
72*d9f75844SAndroid Build Coastguard Worker webrtc::SamplesStatsCounter counter;
73*d9f75844SAndroid Build Coastguard Worker std::string units;
74*d9f75844SAndroid Build Coastguard Worker };
75*d9f75844SAndroid Build Coastguard Worker
76*d9f75844SAndroid Build Coastguard Worker class PlottableCounterPrinter {
77*d9f75844SAndroid Build Coastguard Worker public:
PlottableCounterPrinter()78*d9f75844SAndroid Build Coastguard Worker PlottableCounterPrinter() : output_(stdout) {}
79*d9f75844SAndroid Build Coastguard Worker
SetOutput(FILE * output)80*d9f75844SAndroid Build Coastguard Worker void SetOutput(FILE* output) {
81*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&mutex_);
82*d9f75844SAndroid Build Coastguard Worker output_ = output;
83*d9f75844SAndroid Build Coastguard Worker }
84*d9f75844SAndroid Build Coastguard Worker
AddCounter(absl::string_view graph_name,absl::string_view trace_name,const webrtc::SamplesStatsCounter & counter,absl::string_view units)85*d9f75844SAndroid Build Coastguard Worker void AddCounter(absl::string_view graph_name,
86*d9f75844SAndroid Build Coastguard Worker absl::string_view trace_name,
87*d9f75844SAndroid Build Coastguard Worker const webrtc::SamplesStatsCounter& counter,
88*d9f75844SAndroid Build Coastguard Worker absl::string_view units) {
89*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&mutex_);
90*d9f75844SAndroid Build Coastguard Worker plottable_counters_.push_back({std::string(graph_name),
91*d9f75844SAndroid Build Coastguard Worker std::string(trace_name), counter,
92*d9f75844SAndroid Build Coastguard Worker std::string(units)});
93*d9f75844SAndroid Build Coastguard Worker }
94*d9f75844SAndroid Build Coastguard Worker
Print(const std::vector<std::string> & desired_graphs_raw) const95*d9f75844SAndroid Build Coastguard Worker void Print(const std::vector<std::string>& desired_graphs_raw) const {
96*d9f75844SAndroid Build Coastguard Worker std::set<std::string> desired_graphs(desired_graphs_raw.begin(),
97*d9f75844SAndroid Build Coastguard Worker desired_graphs_raw.end());
98*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&mutex_);
99*d9f75844SAndroid Build Coastguard Worker for (auto& counter : plottable_counters_) {
100*d9f75844SAndroid Build Coastguard Worker if (!desired_graphs.empty()) {
101*d9f75844SAndroid Build Coastguard Worker auto it = desired_graphs.find(counter.graph_name);
102*d9f75844SAndroid Build Coastguard Worker if (it == desired_graphs.end()) {
103*d9f75844SAndroid Build Coastguard Worker continue;
104*d9f75844SAndroid Build Coastguard Worker }
105*d9f75844SAndroid Build Coastguard Worker }
106*d9f75844SAndroid Build Coastguard Worker
107*d9f75844SAndroid Build Coastguard Worker std::ostringstream value_stream;
108*d9f75844SAndroid Build Coastguard Worker value_stream.precision(8);
109*d9f75844SAndroid Build Coastguard Worker value_stream << R"({"graph_name":")" << counter.graph_name << R"(",)";
110*d9f75844SAndroid Build Coastguard Worker value_stream << R"("trace_name":")" << counter.trace_name << R"(",)";
111*d9f75844SAndroid Build Coastguard Worker value_stream << R"("units":")" << counter.units << R"(",)";
112*d9f75844SAndroid Build Coastguard Worker if (!counter.counter.IsEmpty()) {
113*d9f75844SAndroid Build Coastguard Worker value_stream << R"("mean":)" << counter.counter.GetAverage() << ',';
114*d9f75844SAndroid Build Coastguard Worker value_stream << R"("std":)" << counter.counter.GetStandardDeviation()
115*d9f75844SAndroid Build Coastguard Worker << ',';
116*d9f75844SAndroid Build Coastguard Worker }
117*d9f75844SAndroid Build Coastguard Worker value_stream << R"("samples":[)";
118*d9f75844SAndroid Build Coastguard Worker const char* sep = "";
119*d9f75844SAndroid Build Coastguard Worker for (const auto& sample : counter.counter.GetTimedSamples()) {
120*d9f75844SAndroid Build Coastguard Worker value_stream << sep << R"({"time":)" << sample.time.us() << ','
121*d9f75844SAndroid Build Coastguard Worker << R"("value":)" << sample.value << '}';
122*d9f75844SAndroid Build Coastguard Worker sep = ",";
123*d9f75844SAndroid Build Coastguard Worker }
124*d9f75844SAndroid Build Coastguard Worker value_stream << "]}";
125*d9f75844SAndroid Build Coastguard Worker
126*d9f75844SAndroid Build Coastguard Worker fprintf(output_, "PLOTTABLE_DATA: %s\n", value_stream.str().c_str());
127*d9f75844SAndroid Build Coastguard Worker }
128*d9f75844SAndroid Build Coastguard Worker }
129*d9f75844SAndroid Build Coastguard Worker
130*d9f75844SAndroid Build Coastguard Worker private:
131*d9f75844SAndroid Build Coastguard Worker mutable Mutex mutex_;
132*d9f75844SAndroid Build Coastguard Worker std::vector<PlottableCounter> plottable_counters_ RTC_GUARDED_BY(&mutex_);
133*d9f75844SAndroid Build Coastguard Worker FILE* output_ RTC_GUARDED_BY(&mutex_);
134*d9f75844SAndroid Build Coastguard Worker };
135*d9f75844SAndroid Build Coastguard Worker
GetPlottableCounterPrinter()136*d9f75844SAndroid Build Coastguard Worker PlottableCounterPrinter& GetPlottableCounterPrinter() {
137*d9f75844SAndroid Build Coastguard Worker static PlottableCounterPrinter* printer_ = new PlottableCounterPrinter();
138*d9f75844SAndroid Build Coastguard Worker return *printer_;
139*d9f75844SAndroid Build Coastguard Worker }
140*d9f75844SAndroid Build Coastguard Worker
141*d9f75844SAndroid Build Coastguard Worker class ResultsLinePrinter {
142*d9f75844SAndroid Build Coastguard Worker public:
ResultsLinePrinter()143*d9f75844SAndroid Build Coastguard Worker ResultsLinePrinter() : output_(stdout) {}
144*d9f75844SAndroid Build Coastguard Worker
SetOutput(FILE * output)145*d9f75844SAndroid Build Coastguard Worker void SetOutput(FILE* output) {
146*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&mutex_);
147*d9f75844SAndroid Build Coastguard Worker output_ = output;
148*d9f75844SAndroid Build Coastguard Worker }
149*d9f75844SAndroid Build Coastguard Worker
PrintResult(absl::string_view graph_name,absl::string_view trace_name,const double value,absl::string_view units,bool important,ImproveDirection improve_direction)150*d9f75844SAndroid Build Coastguard Worker void PrintResult(absl::string_view graph_name,
151*d9f75844SAndroid Build Coastguard Worker absl::string_view trace_name,
152*d9f75844SAndroid Build Coastguard Worker const double value,
153*d9f75844SAndroid Build Coastguard Worker absl::string_view units,
154*d9f75844SAndroid Build Coastguard Worker bool important,
155*d9f75844SAndroid Build Coastguard Worker ImproveDirection improve_direction) {
156*d9f75844SAndroid Build Coastguard Worker std::ostringstream value_stream;
157*d9f75844SAndroid Build Coastguard Worker value_stream.precision(8);
158*d9f75844SAndroid Build Coastguard Worker value_stream << value;
159*d9f75844SAndroid Build Coastguard Worker
160*d9f75844SAndroid Build Coastguard Worker PrintResultImpl(graph_name, trace_name, value_stream.str(), std::string(),
161*d9f75844SAndroid Build Coastguard Worker std::string(), UnitWithDirection(units, improve_direction),
162*d9f75844SAndroid Build Coastguard Worker important);
163*d9f75844SAndroid Build Coastguard Worker }
164*d9f75844SAndroid Build Coastguard Worker
PrintResultMeanAndError(absl::string_view graph_name,absl::string_view trace_name,const double mean,const double error,absl::string_view units,bool important,ImproveDirection improve_direction)165*d9f75844SAndroid Build Coastguard Worker void PrintResultMeanAndError(absl::string_view graph_name,
166*d9f75844SAndroid Build Coastguard Worker absl::string_view trace_name,
167*d9f75844SAndroid Build Coastguard Worker const double mean,
168*d9f75844SAndroid Build Coastguard Worker const double error,
169*d9f75844SAndroid Build Coastguard Worker absl::string_view units,
170*d9f75844SAndroid Build Coastguard Worker bool important,
171*d9f75844SAndroid Build Coastguard Worker ImproveDirection improve_direction) {
172*d9f75844SAndroid Build Coastguard Worker std::ostringstream value_stream;
173*d9f75844SAndroid Build Coastguard Worker value_stream.precision(8);
174*d9f75844SAndroid Build Coastguard Worker value_stream << mean << ',' << error;
175*d9f75844SAndroid Build Coastguard Worker PrintResultImpl(graph_name, trace_name, value_stream.str(), "{", "}",
176*d9f75844SAndroid Build Coastguard Worker UnitWithDirection(units, improve_direction), important);
177*d9f75844SAndroid Build Coastguard Worker }
178*d9f75844SAndroid Build Coastguard Worker
PrintResultList(absl::string_view graph_name,absl::string_view trace_name,const rtc::ArrayView<const double> values,absl::string_view units,const bool important,webrtc::test::ImproveDirection improve_direction)179*d9f75844SAndroid Build Coastguard Worker void PrintResultList(absl::string_view graph_name,
180*d9f75844SAndroid Build Coastguard Worker absl::string_view trace_name,
181*d9f75844SAndroid Build Coastguard Worker const rtc::ArrayView<const double> values,
182*d9f75844SAndroid Build Coastguard Worker absl::string_view units,
183*d9f75844SAndroid Build Coastguard Worker const bool important,
184*d9f75844SAndroid Build Coastguard Worker webrtc::test::ImproveDirection improve_direction) {
185*d9f75844SAndroid Build Coastguard Worker std::ostringstream value_stream;
186*d9f75844SAndroid Build Coastguard Worker value_stream.precision(8);
187*d9f75844SAndroid Build Coastguard Worker OutputListToStream(&value_stream, values);
188*d9f75844SAndroid Build Coastguard Worker PrintResultImpl(graph_name, trace_name, value_stream.str(), "[", "]", units,
189*d9f75844SAndroid Build Coastguard Worker important);
190*d9f75844SAndroid Build Coastguard Worker }
191*d9f75844SAndroid Build Coastguard Worker
192*d9f75844SAndroid Build Coastguard Worker private:
PrintResultImpl(absl::string_view graph_name,absl::string_view trace_name,absl::string_view values,absl::string_view prefix,absl::string_view suffix,absl::string_view units,bool important)193*d9f75844SAndroid Build Coastguard Worker void PrintResultImpl(absl::string_view graph_name,
194*d9f75844SAndroid Build Coastguard Worker absl::string_view trace_name,
195*d9f75844SAndroid Build Coastguard Worker absl::string_view values,
196*d9f75844SAndroid Build Coastguard Worker absl::string_view prefix,
197*d9f75844SAndroid Build Coastguard Worker absl::string_view suffix,
198*d9f75844SAndroid Build Coastguard Worker absl::string_view units,
199*d9f75844SAndroid Build Coastguard Worker bool important) {
200*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&mutex_);
201*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder message;
202*d9f75844SAndroid Build Coastguard Worker message << (important ? "*" : "") << "RESULT " << graph_name << ": "
203*d9f75844SAndroid Build Coastguard Worker << trace_name << "= " << prefix << values << suffix << " " << units;
204*d9f75844SAndroid Build Coastguard Worker // <*>RESULT <graph_name>: <trace_name>= <value> <units>
205*d9f75844SAndroid Build Coastguard Worker // <*>RESULT <graph_name>: <trace_name>= {<mean>, <std deviation>} <units>
206*d9f75844SAndroid Build Coastguard Worker // <*>RESULT <graph_name>: <trace_name>= [<value>,value,value,...,] <units>
207*d9f75844SAndroid Build Coastguard Worker fprintf(output_, "%s\n", message.str().c_str());
208*d9f75844SAndroid Build Coastguard Worker }
209*d9f75844SAndroid Build Coastguard Worker
210*d9f75844SAndroid Build Coastguard Worker Mutex mutex_;
211*d9f75844SAndroid Build Coastguard Worker FILE* output_ RTC_GUARDED_BY(&mutex_);
212*d9f75844SAndroid Build Coastguard Worker };
213*d9f75844SAndroid Build Coastguard Worker
GetResultsLinePrinter()214*d9f75844SAndroid Build Coastguard Worker ResultsLinePrinter& GetResultsLinePrinter() {
215*d9f75844SAndroid Build Coastguard Worker static ResultsLinePrinter* const printer_ = new ResultsLinePrinter();
216*d9f75844SAndroid Build Coastguard Worker return *printer_;
217*d9f75844SAndroid Build Coastguard Worker }
218*d9f75844SAndroid Build Coastguard Worker
GetPerfWriter()219*d9f75844SAndroid Build Coastguard Worker PerfTestResultWriter& GetPerfWriter() {
220*d9f75844SAndroid Build Coastguard Worker static PerfTestResultWriter* writer = CreateHistogramWriter();
221*d9f75844SAndroid Build Coastguard Worker return *writer;
222*d9f75844SAndroid Build Coastguard Worker }
223*d9f75844SAndroid Build Coastguard Worker
224*d9f75844SAndroid Build Coastguard Worker } // namespace
225*d9f75844SAndroid Build Coastguard Worker
ClearPerfResults()226*d9f75844SAndroid Build Coastguard Worker void ClearPerfResults() {
227*d9f75844SAndroid Build Coastguard Worker GetPerfWriter().ClearResults();
228*d9f75844SAndroid Build Coastguard Worker }
229*d9f75844SAndroid Build Coastguard Worker
SetPerfResultsOutput(FILE * output)230*d9f75844SAndroid Build Coastguard Worker void SetPerfResultsOutput(FILE* output) {
231*d9f75844SAndroid Build Coastguard Worker GetPlottableCounterPrinter().SetOutput(output);
232*d9f75844SAndroid Build Coastguard Worker GetResultsLinePrinter().SetOutput(output);
233*d9f75844SAndroid Build Coastguard Worker }
234*d9f75844SAndroid Build Coastguard Worker
GetPerfResults()235*d9f75844SAndroid Build Coastguard Worker std::string GetPerfResults() {
236*d9f75844SAndroid Build Coastguard Worker return GetPerfWriter().Serialize();
237*d9f75844SAndroid Build Coastguard Worker }
238*d9f75844SAndroid Build Coastguard Worker
PrintPlottableResults(const std::vector<std::string> & desired_graphs)239*d9f75844SAndroid Build Coastguard Worker void PrintPlottableResults(const std::vector<std::string>& desired_graphs) {
240*d9f75844SAndroid Build Coastguard Worker GetPlottableCounterPrinter().Print(desired_graphs);
241*d9f75844SAndroid Build Coastguard Worker }
242*d9f75844SAndroid Build Coastguard Worker
WritePerfResults(const std::string & output_path)243*d9f75844SAndroid Build Coastguard Worker bool WritePerfResults(const std::string& output_path) {
244*d9f75844SAndroid Build Coastguard Worker std::string results = GetPerfResults();
245*d9f75844SAndroid Build Coastguard Worker CreateDir(DirName(output_path));
246*d9f75844SAndroid Build Coastguard Worker FILE* output = fopen(output_path.c_str(), "wb");
247*d9f75844SAndroid Build Coastguard Worker if (output == NULL) {
248*d9f75844SAndroid Build Coastguard Worker printf("Failed to write to %s.\n", output_path.c_str());
249*d9f75844SAndroid Build Coastguard Worker return false;
250*d9f75844SAndroid Build Coastguard Worker }
251*d9f75844SAndroid Build Coastguard Worker size_t written =
252*d9f75844SAndroid Build Coastguard Worker fwrite(results.c_str(), sizeof(char), results.size(), output);
253*d9f75844SAndroid Build Coastguard Worker fclose(output);
254*d9f75844SAndroid Build Coastguard Worker
255*d9f75844SAndroid Build Coastguard Worker if (written != results.size()) {
256*d9f75844SAndroid Build Coastguard Worker long expected = results.size();
257*d9f75844SAndroid Build Coastguard Worker printf("Wrote %zu, tried to write %lu\n", written, expected);
258*d9f75844SAndroid Build Coastguard Worker return false;
259*d9f75844SAndroid Build Coastguard Worker }
260*d9f75844SAndroid Build Coastguard Worker
261*d9f75844SAndroid Build Coastguard Worker return true;
262*d9f75844SAndroid Build Coastguard Worker }
263*d9f75844SAndroid Build Coastguard Worker
PrintResult(absl::string_view measurement,absl::string_view modifier,absl::string_view trace,const double value,absl::string_view units,bool important,ImproveDirection improve_direction)264*d9f75844SAndroid Build Coastguard Worker void PrintResult(absl::string_view measurement,
265*d9f75844SAndroid Build Coastguard Worker absl::string_view modifier,
266*d9f75844SAndroid Build Coastguard Worker absl::string_view trace,
267*d9f75844SAndroid Build Coastguard Worker const double value,
268*d9f75844SAndroid Build Coastguard Worker absl::string_view units,
269*d9f75844SAndroid Build Coastguard Worker bool important,
270*d9f75844SAndroid Build Coastguard Worker ImproveDirection improve_direction) {
271*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder graph_name;
272*d9f75844SAndroid Build Coastguard Worker graph_name << measurement << modifier;
273*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(std::isfinite(value))
274*d9f75844SAndroid Build Coastguard Worker << "Expected finite value for graph " << graph_name.str()
275*d9f75844SAndroid Build Coastguard Worker << ", trace name " << trace << ", units " << units << ", got " << value;
276*d9f75844SAndroid Build Coastguard Worker GetPerfWriter().LogResult(graph_name.str(), trace, value, units, important,
277*d9f75844SAndroid Build Coastguard Worker improve_direction);
278*d9f75844SAndroid Build Coastguard Worker GetResultsLinePrinter().PrintResult(graph_name.str(), trace, value, units,
279*d9f75844SAndroid Build Coastguard Worker important, improve_direction);
280*d9f75844SAndroid Build Coastguard Worker }
281*d9f75844SAndroid Build Coastguard Worker
PrintResult(absl::string_view measurement,absl::string_view modifier,absl::string_view trace,const SamplesStatsCounter & counter,absl::string_view units,const bool important,ImproveDirection improve_direction)282*d9f75844SAndroid Build Coastguard Worker void PrintResult(absl::string_view measurement,
283*d9f75844SAndroid Build Coastguard Worker absl::string_view modifier,
284*d9f75844SAndroid Build Coastguard Worker absl::string_view trace,
285*d9f75844SAndroid Build Coastguard Worker const SamplesStatsCounter& counter,
286*d9f75844SAndroid Build Coastguard Worker absl::string_view units,
287*d9f75844SAndroid Build Coastguard Worker const bool important,
288*d9f75844SAndroid Build Coastguard Worker ImproveDirection improve_direction) {
289*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder graph_name;
290*d9f75844SAndroid Build Coastguard Worker graph_name << measurement << modifier;
291*d9f75844SAndroid Build Coastguard Worker GetPlottableCounterPrinter().AddCounter(graph_name.str(), trace, counter,
292*d9f75844SAndroid Build Coastguard Worker units);
293*d9f75844SAndroid Build Coastguard Worker
294*d9f75844SAndroid Build Coastguard Worker double mean = counter.IsEmpty() ? 0 : counter.GetAverage();
295*d9f75844SAndroid Build Coastguard Worker double error = counter.IsEmpty() ? 0 : counter.GetStandardDeviation();
296*d9f75844SAndroid Build Coastguard Worker
297*d9f75844SAndroid Build Coastguard Worker std::vector<SamplesStatsCounter::StatsSample> timed_samples =
298*d9f75844SAndroid Build Coastguard Worker GetSortedSamples(counter);
299*d9f75844SAndroid Build Coastguard Worker std::vector<double> samples(timed_samples.size());
300*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < timed_samples.size(); ++i) {
301*d9f75844SAndroid Build Coastguard Worker samples[i] = timed_samples[i].value;
302*d9f75844SAndroid Build Coastguard Worker }
303*d9f75844SAndroid Build Coastguard Worker // If we have an empty counter, default it to 0.
304*d9f75844SAndroid Build Coastguard Worker if (samples.empty()) {
305*d9f75844SAndroid Build Coastguard Worker samples.push_back(0);
306*d9f75844SAndroid Build Coastguard Worker }
307*d9f75844SAndroid Build Coastguard Worker
308*d9f75844SAndroid Build Coastguard Worker GetPerfWriter().LogResultList(graph_name.str(), trace, samples, units,
309*d9f75844SAndroid Build Coastguard Worker important, improve_direction);
310*d9f75844SAndroid Build Coastguard Worker GetResultsLinePrinter().PrintResultMeanAndError(graph_name.str(), trace, mean,
311*d9f75844SAndroid Build Coastguard Worker error, units, important,
312*d9f75844SAndroid Build Coastguard Worker improve_direction);
313*d9f75844SAndroid Build Coastguard Worker }
314*d9f75844SAndroid Build Coastguard Worker
PrintResultMeanAndError(absl::string_view measurement,absl::string_view modifier,absl::string_view trace,const double mean,const double error,absl::string_view units,bool important,ImproveDirection improve_direction)315*d9f75844SAndroid Build Coastguard Worker void PrintResultMeanAndError(absl::string_view measurement,
316*d9f75844SAndroid Build Coastguard Worker absl::string_view modifier,
317*d9f75844SAndroid Build Coastguard Worker absl::string_view trace,
318*d9f75844SAndroid Build Coastguard Worker const double mean,
319*d9f75844SAndroid Build Coastguard Worker const double error,
320*d9f75844SAndroid Build Coastguard Worker absl::string_view units,
321*d9f75844SAndroid Build Coastguard Worker bool important,
322*d9f75844SAndroid Build Coastguard Worker ImproveDirection improve_direction) {
323*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(std::isfinite(mean));
324*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(std::isfinite(error));
325*d9f75844SAndroid Build Coastguard Worker
326*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder graph_name;
327*d9f75844SAndroid Build Coastguard Worker graph_name << measurement << modifier;
328*d9f75844SAndroid Build Coastguard Worker GetPerfWriter().LogResultMeanAndError(graph_name.str(), trace, mean, error,
329*d9f75844SAndroid Build Coastguard Worker units, important, improve_direction);
330*d9f75844SAndroid Build Coastguard Worker GetResultsLinePrinter().PrintResultMeanAndError(graph_name.str(), trace, mean,
331*d9f75844SAndroid Build Coastguard Worker error, units, important,
332*d9f75844SAndroid Build Coastguard Worker improve_direction);
333*d9f75844SAndroid Build Coastguard Worker }
334*d9f75844SAndroid Build Coastguard Worker
PrintResultList(absl::string_view measurement,absl::string_view modifier,absl::string_view trace,const rtc::ArrayView<const double> values,absl::string_view units,bool important,ImproveDirection improve_direction)335*d9f75844SAndroid Build Coastguard Worker void PrintResultList(absl::string_view measurement,
336*d9f75844SAndroid Build Coastguard Worker absl::string_view modifier,
337*d9f75844SAndroid Build Coastguard Worker absl::string_view trace,
338*d9f75844SAndroid Build Coastguard Worker const rtc::ArrayView<const double> values,
339*d9f75844SAndroid Build Coastguard Worker absl::string_view units,
340*d9f75844SAndroid Build Coastguard Worker bool important,
341*d9f75844SAndroid Build Coastguard Worker ImproveDirection improve_direction) {
342*d9f75844SAndroid Build Coastguard Worker for (double v : values) {
343*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(std::isfinite(v));
344*d9f75844SAndroid Build Coastguard Worker }
345*d9f75844SAndroid Build Coastguard Worker
346*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder graph_name;
347*d9f75844SAndroid Build Coastguard Worker graph_name << measurement << modifier;
348*d9f75844SAndroid Build Coastguard Worker GetPerfWriter().LogResultList(graph_name.str(), trace, values, units,
349*d9f75844SAndroid Build Coastguard Worker important, improve_direction);
350*d9f75844SAndroid Build Coastguard Worker GetResultsLinePrinter().PrintResultList(graph_name.str(), trace, values,
351*d9f75844SAndroid Build Coastguard Worker units, important, improve_direction);
352*d9f75844SAndroid Build Coastguard Worker }
353*d9f75844SAndroid Build Coastguard Worker
354*d9f75844SAndroid Build Coastguard Worker } // namespace test
355*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
356