1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "perf_test.h"
6
7 #include "common/third_party/base/anglebase/no_destructor.h"
8
9 #include <stdarg.h>
10 #include <stdio.h>
11 #include <vector>
12
13 namespace
14 {
15
FormatString(const char * fmt,va_list vararg)16 std::string FormatString(const char *fmt, va_list vararg)
17 {
18 static angle::base::NoDestructor<std::vector<char>> buffer(512);
19
20 // Attempt to just print to the current buffer
21 int len = vsnprintf(buffer->data(), buffer->size(), fmt, vararg);
22 if (len < 0 || static_cast<size_t>(len) >= buffer->size())
23 {
24 // Buffer was not large enough, calculate the required size and resize the buffer
25 len = vsnprintf(NULL, 0, fmt, vararg);
26 buffer->resize(len + 1);
27
28 // Print again
29 vsnprintf(buffer->data(), buffer->size(), fmt, vararg);
30 }
31
32 return std::string(buffer->data(), len);
33 }
34
StringPrintf(const char * fmt,...)35 std::string StringPrintf(const char *fmt, ...)
36 {
37 va_list vararg;
38 va_start(vararg, fmt);
39 std::string result = FormatString(fmt, vararg);
40 va_end(vararg);
41 return result;
42 }
43
NumberToString(size_t value)44 std::string NumberToString(size_t value)
45 {
46 return StringPrintf("%u", value);
47 }
48
NumberToString(double value)49 std::string NumberToString(double value)
50 {
51 return StringPrintf("%.10lf", value);
52 }
53
ResultsToString(const std::string & measurement,const std::string & modifier,const std::string & trace,const std::string & values,const std::string & prefix,const std::string & suffix,const std::string & units,bool important)54 std::string ResultsToString(const std::string &measurement,
55 const std::string &modifier,
56 const std::string &trace,
57 const std::string &values,
58 const std::string &prefix,
59 const std::string &suffix,
60 const std::string &units,
61 bool important)
62 {
63 // <*>RESULT <graph_name>: <trace_name>= <value> <units>
64 // <*>RESULT <graph_name>: <trace_name>= {<mean>, <std deviation>} <units>
65 // <*>RESULT <graph_name>: <trace_name>= [<value>,value,value,...,] <units>
66 return StringPrintf("%sRESULT %s%s: %s= %s%s%s %s\n", important ? "*" : "", measurement.c_str(),
67 modifier.c_str(), trace.c_str(), prefix.c_str(), values.c_str(),
68 suffix.c_str(), units.c_str());
69 }
70
PrintResultsImpl(const std::string & measurement,const std::string & modifier,const std::string & trace,const std::string & values,const std::string & prefix,const std::string & suffix,const std::string & units,bool important)71 void PrintResultsImpl(const std::string &measurement,
72 const std::string &modifier,
73 const std::string &trace,
74 const std::string &values,
75 const std::string &prefix,
76 const std::string &suffix,
77 const std::string &units,
78 bool important)
79 {
80 fflush(stdout);
81 printf("%s",
82 ResultsToString(measurement, modifier, trace, values, prefix, suffix, units, important)
83 .c_str());
84 fflush(stdout);
85 }
86
87 } // namespace
88
89 namespace perf_test
90 {
91
PrintResult(const std::string & measurement,const std::string & modifier,const std::string & trace,size_t value,const std::string & units,bool important)92 void PrintResult(const std::string &measurement,
93 const std::string &modifier,
94 const std::string &trace,
95 size_t value,
96 const std::string &units,
97 bool important)
98 {
99 PrintResultsImpl(measurement, modifier, trace, NumberToString(value), std::string(),
100 std::string(), units, important);
101 }
102
PrintResult(const std::string & measurement,const std::string & modifier,const std::string & trace,double value,const std::string & units,bool important)103 void PrintResult(const std::string &measurement,
104 const std::string &modifier,
105 const std::string &trace,
106 double value,
107 const std::string &units,
108 bool important)
109 {
110 PrintResultsImpl(measurement, modifier, trace, NumberToString(value), std::string(),
111 std::string(), units, important);
112 }
113
AppendResult(std::string & output,const std::string & measurement,const std::string & modifier,const std::string & trace,size_t value,const std::string & units,bool important)114 void AppendResult(std::string &output,
115 const std::string &measurement,
116 const std::string &modifier,
117 const std::string &trace,
118 size_t value,
119 const std::string &units,
120 bool important)
121 {
122 output += ResultsToString(measurement, modifier, trace, NumberToString(value), std::string(),
123 std::string(), units, important);
124 }
125
PrintResult(const std::string & measurement,const std::string & modifier,const std::string & trace,const std::string & value,const std::string & units,bool important)126 void PrintResult(const std::string &measurement,
127 const std::string &modifier,
128 const std::string &trace,
129 const std::string &value,
130 const std::string &units,
131 bool important)
132 {
133 PrintResultsImpl(measurement, modifier, trace, value, std::string(), std::string(), units,
134 important);
135 }
136
AppendResult(std::string & output,const std::string & measurement,const std::string & modifier,const std::string & trace,const std::string & value,const std::string & units,bool important)137 void AppendResult(std::string &output,
138 const std::string &measurement,
139 const std::string &modifier,
140 const std::string &trace,
141 const std::string &value,
142 const std::string &units,
143 bool important)
144 {
145 output += ResultsToString(measurement, modifier, trace, value, std::string(), std::string(),
146 units, important);
147 }
148
PrintResultMeanAndError(const std::string & measurement,const std::string & modifier,const std::string & trace,const std::string & mean_and_error,const std::string & units,bool important)149 void PrintResultMeanAndError(const std::string &measurement,
150 const std::string &modifier,
151 const std::string &trace,
152 const std::string &mean_and_error,
153 const std::string &units,
154 bool important)
155 {
156 PrintResultsImpl(measurement, modifier, trace, mean_and_error, "{", "}", units, important);
157 }
158
AppendResultMeanAndError(std::string & output,const std::string & measurement,const std::string & modifier,const std::string & trace,const std::string & mean_and_error,const std::string & units,bool important)159 void AppendResultMeanAndError(std::string &output,
160 const std::string &measurement,
161 const std::string &modifier,
162 const std::string &trace,
163 const std::string &mean_and_error,
164 const std::string &units,
165 bool important)
166 {
167 output +=
168 ResultsToString(measurement, modifier, trace, mean_and_error, "{", "}", units, important);
169 }
170
PrintResultList(const std::string & measurement,const std::string & modifier,const std::string & trace,const std::string & values,const std::string & units,bool important)171 void PrintResultList(const std::string &measurement,
172 const std::string &modifier,
173 const std::string &trace,
174 const std::string &values,
175 const std::string &units,
176 bool important)
177 {
178 PrintResultsImpl(measurement, modifier, trace, values, "[", "]", units, important);
179 }
180
AppendResultList(std::string & output,const std::string & measurement,const std::string & modifier,const std::string & trace,const std::string & values,const std::string & units,bool important)181 void AppendResultList(std::string &output,
182 const std::string &measurement,
183 const std::string &modifier,
184 const std::string &trace,
185 const std::string &values,
186 const std::string &units,
187 bool important)
188 {
189 output += ResultsToString(measurement, modifier, trace, values, "[", "]", units, important);
190 }
191
PrintSystemCommitCharge(const std::string & test_name,size_t charge,bool important)192 void PrintSystemCommitCharge(const std::string &test_name, size_t charge, bool important)
193 {
194 PrintSystemCommitCharge(stdout, test_name, charge, important);
195 }
196
PrintSystemCommitCharge(FILE * target,const std::string & test_name,size_t charge,bool important)197 void PrintSystemCommitCharge(FILE *target,
198 const std::string &test_name,
199 size_t charge,
200 bool important)
201 {
202 fprintf(target, "%s", SystemCommitChargeToString(test_name, charge, important).c_str());
203 }
204
SystemCommitChargeToString(const std::string & test_name,size_t charge,bool important)205 std::string SystemCommitChargeToString(const std::string &test_name, size_t charge, bool important)
206 {
207 std::string trace_name(test_name);
208 std::string output;
209 AppendResult(output, "commit_charge", std::string(), "cc" + trace_name, charge, "kb",
210 important);
211 return output;
212 }
213
214 } // namespace perf_test
215