Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: bench/ResultsWriter.h

Issue 488213002: Add --properties for things like gitHash that describe the current nanobench run. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: styled, comments Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | bench/ResultsWriter.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 * 6 *
7 * Classes for writing out bench results in various formats. 7 * Classes for writing out bench results in various formats.
8 */ 8 */
9 9
10 #ifndef SkResultsWriter_DEFINED 10 #ifndef SkResultsWriter_DEFINED
11 #define SkResultsWriter_DEFINED 11 #define SkResultsWriter_DEFINED
12 12
13 #include "BenchLogger.h" 13 #include "BenchLogger.h"
14 #include "SkJSONCPP.h" 14 #include "SkJSONCPP.h"
15 #include "SkStream.h" 15 #include "SkStream.h"
16 #include "SkString.h" 16 #include "SkString.h"
17 #include "SkTArray.h" 17 #include "SkTArray.h"
18 #include "SkTypes.h" 18 #include "SkTypes.h"
19 19
20 /** 20 /**
21 * Base class for writing out the bench results. 21 * Base class for writing out the bench results.
22 * 22 *
23 * TODO(jcgregorio) Add info if tests fail to converge? 23 * Default implementation does nothing.
24 */ 24 */
25 class ResultsWriter : SkNoncopyable { 25 class ResultsWriter : SkNoncopyable {
26 public: 26 public:
27 virtual ~ResultsWriter() {}; 27 virtual ~ResultsWriter() {}
28 28
29 // Records one key value pair that makes up a unique identifier for this run . 29 // Record one key value pair that makes up a unique key for this type of run , e.g.
30 // All keys must be set before calling bench(). 30 // builder name, machine type, Debug/Release, etc.
31 virtual void key(const char name[], const char value[]) = 0; 31 virtual void key(const char name[], const char value[]) {}
32 32
33 // Records one option set for this run. All options must be set before 33 // Record one key value pair that describes the run instance, e.g. git hash, build number.
34 // calling bench(). 34 virtual void property(const char name[], const char value[]) {}
35 virtual void option(const char name[], const char value[]) = 0;
36 35
37 // Denotes the start of a specific benchmark. Once bench is called, 36 // Denote the start of a specific benchmark. Once bench is called,
38 // then config and timer can be called multiple times to record runs. 37 // then config and timer can be called multiple times to record runs.
39 virtual void bench(const char name[], int32_t x, int32_t y) = 0; 38 virtual void bench(const char name[], int32_t x, int32_t y) {}
40 39
41 // Records the specific configuration a bench is run under, such as "8888". 40 // Record the specific configuration a bench is run under, such as "8888".
42 virtual void config(const char name[]) = 0; 41 virtual void config(const char name[]) {}
43 42
44 // Records the options for a configuration, such as "GL_RENDERER". 43 // Record the options for a configuration, such as "GL_RENDERER".
45 virtual void configOption(const char name[], const char* value) = 0; 44 virtual void configOption(const char name[], const char* value) {}
46 45
47 // Records a single test metric. 46 // Record a single test metric.
48 virtual void timer(const char name[], double ms) = 0; 47 virtual void timer(const char name[], double ms) {}
49
50 // Call when all results are finished.
51 virtual void end() = 0;
52 }; 48 };
53 49
54 /** 50 /**
55 * This ResultsWriter handles writing out the human readable format of the
56 * bench results.
57 */
58 class LoggerResultsWriter : public ResultsWriter {
59 public:
60 explicit LoggerResultsWriter(BenchLogger& logger, const char* timeFormat)
61 : fLogger(logger)
62 , fTimeFormat(timeFormat) {
63 fLogger.logProgress("skia bench:");
64 }
65 virtual void key(const char name[], const char value[]) {
66 // Don't log keys to keep microbench output unchanged.
67 }
68 virtual void option(const char name[], const char value[]) {
69 fLogger.logProgress(SkStringPrintf(" %s=%s", name, value));
70 }
71 virtual void bench(const char name[], int32_t x, int32_t y) {
72 fLogger.logProgress(SkStringPrintf(
73 "\nrunning bench [%3d %3d] %40s", x, y, name));
74 }
75 virtual void config(const char name[]) {
76 fLogger.logProgress(SkStringPrintf(" %s:", name));
77 }
78 virtual void configOption(const char name[], const char* value) {
79 // Don't log configOptions to keep microbench output unchanged.
80 }
81 virtual void timer(const char name[], double ms) {
82 fLogger.logProgress(SkStringPrintf(" %s = ", name));
83 fLogger.logProgress(SkStringPrintf(fTimeFormat, ms));
84 }
85 virtual void end() {
86 fLogger.logProgress("\n");
87 }
88 private:
89 BenchLogger& fLogger;
90 const char* fTimeFormat;
91 };
92
93 /**
94 * This ResultsWriter handles writing out the results in JSON.
95 *
96 * The output looks like (except compressed to a single line):
97 *
98 * {
99 * "options" : {
100 * "alpha" : "0xFF",
101 * "scale" : "0",
102 * ...
103 * "system" : "UNIX"
104 * },
105 * "results" : [
106 * {
107 * "name" : "Xfermode_Luminosity_640_480",
108 * "results" : [
109 * {
110 * "name": "565",
111 * "cmsecs" : 143.188128906250,
112 * "msecs" : 143.835957031250
113 * },
114 * ...
115 */
116
117 Json::Value* SkFindNamedNode(Json::Value* root, const char name[]);
118 Json::Value SkMakeBuilderJSON(const SkString &buildername);
119
120 class JSONResultsWriter : public ResultsWriter {
121 public:
122 explicit JSONResultsWriter(const char filename[])
123 : fFilename(filename)
124 , fRoot()
125 , fResults(fRoot["results"])
126 , fBench(NULL)
127 , fConfig(NULL) {
128 }
129 virtual void key(const char name[], const char value[]) {
130 }
131 virtual void option(const char name[], const char value[]) {
132 fRoot["options"][name] = value;
133 }
134 virtual void bench(const char name[], int32_t x, int32_t y) {
135 SkString sk_name(name);
136 sk_name.append("_");
137 sk_name.appendS32(x);
138 sk_name.append("_");
139 sk_name.appendS32(y);
140 Json::Value* bench_node = SkFindNamedNode(&fResults, sk_name.c_str());
141 fBench = &(*bench_node)["results"];
142 }
143 virtual void config(const char name[]) {
144 SkASSERT(NULL != fBench);
145 fConfig = SkFindNamedNode(fBench, name);
146 }
147 virtual void configOption(const char name[], const char* value) {
148 }
149 virtual void timer(const char name[], double ms) {
150 SkASSERT(NULL != fConfig);
151 (*fConfig)[name] = ms;
152 }
153 virtual void end() {
154 SkFILEWStream stream(fFilename.c_str());
155 stream.writeText(Json::FastWriter().write(fRoot).c_str());
156 stream.flush();
157 }
158 private:
159
160 SkString fFilename;
161 Json::Value fRoot;
162 Json::Value& fResults;
163 Json::Value* fBench;
164 Json::Value* fConfig;
165 };
166
167 /**
168 NanoJSONResultsWriter writes the test results out in the following 51 NanoJSONResultsWriter writes the test results out in the following
169 format: 52 format:
170 53
171 { 54 {
172 "key": { 55 "key": {
173 "arch": "Arm7", 56 "arch": "Arm7",
174 "gpu": "SGX540", 57 "gpu": "SGX540",
175 "os": "Android", 58 "os": "Android",
176 "model": "GalaxyNexus", 59 "model": "GalaxyNexus",
177 } 60 }
178 "options": {
179 "GL_Version": "3.1",
180 ...
181 },
182 "gitHash": "d1830323662ae8ae06908b97f15180fd25808894", 61 "gitHash": "d1830323662ae8ae06908b97f15180fd25808894",
62 "build_number": "1234",
183 "results" : { 63 "results" : {
184 "Xfermode_Luminosity_640_480" : { 64 "Xfermode_Luminosity_640_480" : {
185 "8888" : { 65 "8888" : {
186 "median_ms" : 143.188128906250, 66 "median_ms" : 143.188128906250,
187 "min_ms" : 143.835957031250, 67 "min_ms" : 143.835957031250,
188 ... 68 ...
189 }, 69 },
190 ... 70 ...
191 */ 71 */
192 class NanoJSONResultsWriter : public ResultsWriter { 72 class NanoJSONResultsWriter : public ResultsWriter {
193 public: 73 public:
194 explicit NanoJSONResultsWriter(const char filename[], const char gitHash[]) 74 explicit NanoJSONResultsWriter(const char filename[])
195 : fFilename(filename) 75 : fFilename(filename)
196 , fRoot() 76 , fRoot()
197 , fResults(fRoot["results"]) 77 , fResults(fRoot["results"])
198 , fBench(NULL) 78 , fBench(NULL)
199 , fConfig(NULL) { 79 , fConfig(NULL) {}
200 fRoot["gitHash"] = gitHash; 80
81 ~NanoJSONResultsWriter() {
82 SkFILEWStream stream(fFilename.c_str());
83 stream.writeText(Json::StyledWriter().write(fRoot).c_str());
84 stream.flush();
201 } 85 }
86
87 // Added under "key".
202 virtual void key(const char name[], const char value[]) { 88 virtual void key(const char name[], const char value[]) {
203 fRoot["key"][name] = value; 89 fRoot["key"][name] = value;
204 } 90 }
205 virtual void option(const char name[], const char value[]) { 91 // Inserted directly into the root.
206 fRoot["options"][name] = value; 92 virtual void property(const char name[], const char value[]) {
93 fRoot[name] = value;
207 } 94 }
208 virtual void bench(const char name[], int32_t x, int32_t y) { 95 virtual void bench(const char name[], int32_t x, int32_t y) {
209 SkString id = SkStringPrintf( "%s_%d_%d", name, x, y); 96 SkString id = SkStringPrintf( "%s_%d_%d", name, x, y);
210 fResults[id.c_str()] = Json::Value(Json::objectValue); 97 fResults[id.c_str()] = Json::Value(Json::objectValue);
211 fBench = &fResults[id.c_str()]; 98 fBench = &fResults[id.c_str()];
212 } 99 }
213 virtual void config(const char name[]) { 100 virtual void config(const char name[]) {
214 SkASSERT(NULL != fBench); 101 SkASSERT(NULL != fBench);
215 fConfig = &(*fBench)[name]; 102 fConfig = &(*fBench)[name];
216 } 103 }
217 virtual void configOption(const char name[], const char* value) { 104 virtual void configOption(const char name[], const char* value) {
218 (*fConfig)["options"][name] = value; 105 (*fConfig)["options"][name] = value;
219 } 106 }
220 virtual void timer(const char name[], double ms) { 107 virtual void timer(const char name[], double ms) {
221 // Don't record if nan, or -nan. 108 // Don't record if nan, or -nan.
222 if (sk_double_isnan(ms)) { 109 if (sk_double_isnan(ms)) {
223 return; 110 return;
224 } 111 }
225 SkASSERT(NULL != fConfig); 112 SkASSERT(NULL != fConfig);
226 (*fConfig)[name] = ms; 113 (*fConfig)[name] = ms;
227 } 114 }
228 virtual void end() { 115
229 SkFILEWStream stream(fFilename.c_str());
230 stream.writeText(Json::FastWriter().write(fRoot).c_str());
231 stream.flush();
232 }
233 private: 116 private:
234
235 SkString fFilename; 117 SkString fFilename;
236 Json::Value fRoot; 118 Json::Value fRoot;
237 Json::Value& fResults; 119 Json::Value& fResults;
238 Json::Value* fBench; 120 Json::Value* fBench;
239 Json::Value* fConfig; 121 Json::Value* fConfig;
240 }; 122 };
241 123
242 124
243 /**
244 * This ResultsWriter writes out to multiple ResultsWriters.
245 */
246 class MultiResultsWriter : public ResultsWriter {
247 public:
248 MultiResultsWriter() : writers() {
249 };
250 void add(ResultsWriter* writer) {
251 writers.push_back(writer);
252 }
253 virtual void key(const char name[], const char value[]) {
254 for (int i = 0; i < writers.count(); ++i) {
255 writers[i]->key(name, value);
256 }
257 }
258 virtual void option(const char name[], const char value[]) {
259 for (int i = 0; i < writers.count(); ++i) {
260 writers[i]->option(name, value);
261 }
262 }
263 virtual void bench(const char name[], int32_t x, int32_t y) {
264 for (int i = 0; i < writers.count(); ++i) {
265 writers[i]->bench(name, x, y);
266 }
267 }
268 virtual void config(const char name[]) {
269 for (int i = 0; i < writers.count(); ++i) {
270 writers[i]->config(name);
271 }
272 }
273 virtual void configOption(const char name[], const char* value) {
274 for (int i = 0; i < writers.count(); ++i) {
275 writers[i]->configOption(name, value);
276 }
277 }
278 virtual void timer(const char name[], double ms) {
279 for (int i = 0; i < writers.count(); ++i) {
280 writers[i]->timer(name, ms);
281 }
282 }
283 virtual void end() {
284 for (int i = 0; i < writers.count(); ++i) {
285 writers[i]->end();
286 }
287 }
288 private:
289 SkTArray<ResultsWriter *> writers;
290 };
291
292 /**
293 * Calls the end() method of T on destruction.
294 */
295 template <typename T> class CallEnd : SkNoncopyable {
296 public:
297 CallEnd(T& obj) : fObj(obj) {}
298 ~CallEnd() { fObj.end(); }
299 private:
300 T& fObj;
301 };
302
303 #endif 125 #endif
OLDNEW
« no previous file with comments | « no previous file | bench/ResultsWriter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698