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

Side by Side Diff: bench/ResultsWriter.h

Issue 392393002: Change JSON output of nanobench. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 5 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/nanobench.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 * TODO(jcgregorio) Add info if tests fail to converge?
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 .
30 // All keys must be set before calling bench().
31 virtual void key(const char name[], const char value[]) = 0;
32
29 // Records one option set for this run. All options must be set before 33 // Records one option set for this run. All options must be set before
30 // calling bench(). 34 // calling bench().
31 virtual void option(const char name[], const char value[]) = 0; 35 virtual void option(const char name[], const char value[]) = 0;
32 36
33 // Denotes the start of a specific benchmark. Once bench is called, 37 // Denotes the start of a specific benchmark. Once bench is called,
34 // then config and timer can be called multiple times to record runs. 38 // then config and timer can be called multiple times to record runs.
35 virtual void bench(const char name[], int32_t x, int32_t y) = 0; 39 virtual void bench(const char name[], int32_t x, int32_t y) = 0;
36 40
37 // Records the specific configuration a bench is run under, such as "8888". 41 // Records the specific configuration a bench is run under, such as "8888".
38 virtual void config(const char name[]) = 0; 42 virtual void config(const char name[]) = 0;
39 43
44 // Records the options for a configuration, such as "GL_RENDERER".
45 virtual void configOption(const char name[], const char* value) = 0;
46
40 // Records a single test metric. 47 // Records a single test metric.
41 virtual void timer(const char name[], double ms) = 0; 48 virtual void timer(const char name[], double ms) = 0;
42 49
43 // Call when all results are finished. 50 // Call when all results are finished.
44 virtual void end() = 0; 51 virtual void end() = 0;
45 }; 52 };
46 53
47 /** 54 /**
48 * This ResultsWriter handles writing out the human readable format of the 55 * This ResultsWriter handles writing out the human readable format of the
49 * bench results. 56 * bench results.
50 */ 57 */
51 class LoggerResultsWriter : public ResultsWriter { 58 class LoggerResultsWriter : public ResultsWriter {
52 public: 59 public:
53 explicit LoggerResultsWriter(BenchLogger& logger, const char* timeFormat) 60 explicit LoggerResultsWriter(BenchLogger& logger, const char* timeFormat)
54 : fLogger(logger) 61 : fLogger(logger)
55 , fTimeFormat(timeFormat) { 62 , fTimeFormat(timeFormat) {
56 fLogger.logProgress("skia bench:"); 63 fLogger.logProgress("skia bench:");
57 } 64 }
65 virtual void key(const char name[], const char value[]) {
66 // Don't log keys to keep microbench output unchanged.
67 }
58 virtual void option(const char name[], const char value[]) { 68 virtual void option(const char name[], const char value[]) {
59 fLogger.logProgress(SkStringPrintf(" %s=%s", name, value)); 69 fLogger.logProgress(SkStringPrintf(" %s=%s", name, value));
60 } 70 }
61 virtual void bench(const char name[], int32_t x, int32_t y) { 71 virtual void bench(const char name[], int32_t x, int32_t y) {
62 fLogger.logProgress(SkStringPrintf( 72 fLogger.logProgress(SkStringPrintf(
63 "\nrunning bench [%3d %3d] %40s", x, y, name)); 73 "\nrunning bench [%3d %3d] %40s", x, y, name));
64 } 74 }
65 virtual void config(const char name[]) { 75 virtual void config(const char name[]) {
66 fLogger.logProgress(SkStringPrintf(" %s:", name)); 76 fLogger.logProgress(SkStringPrintf(" %s:", name));
67 } 77 }
78 virtual void configOption(const char name[], const char* value) {
79 // Don't log configOptions to keep microbench output unchanged.
80 }
68 virtual void timer(const char name[], double ms) { 81 virtual void timer(const char name[], double ms) {
69 fLogger.logProgress(SkStringPrintf(" %s = ", name)); 82 fLogger.logProgress(SkStringPrintf(" %s = ", name));
70 fLogger.logProgress(SkStringPrintf(fTimeFormat, ms)); 83 fLogger.logProgress(SkStringPrintf(fTimeFormat, ms));
71 } 84 }
72 virtual void end() { 85 virtual void end() {
73 fLogger.logProgress("\n"); 86 fLogger.logProgress("\n");
74 } 87 }
75 private: 88 private:
76 BenchLogger& fLogger; 89 BenchLogger& fLogger;
77 const char* fTimeFormat; 90 const char* fTimeFormat;
(...skipping 28 matching lines...) Expand all
106 119
107 class JSONResultsWriter : public ResultsWriter { 120 class JSONResultsWriter : public ResultsWriter {
108 public: 121 public:
109 explicit JSONResultsWriter(const char filename[]) 122 explicit JSONResultsWriter(const char filename[])
110 : fFilename(filename) 123 : fFilename(filename)
111 , fRoot() 124 , fRoot()
112 , fResults(fRoot["results"]) 125 , fResults(fRoot["results"])
113 , fBench(NULL) 126 , fBench(NULL)
114 , fConfig(NULL) { 127 , fConfig(NULL) {
115 } 128 }
129 virtual void key(const char name[], const char value[]) {
130 }
116 virtual void option(const char name[], const char value[]) { 131 virtual void option(const char name[], const char value[]) {
117 fRoot["options"][name] = value; 132 fRoot["options"][name] = value;
118 } 133 }
119 virtual void bench(const char name[], int32_t x, int32_t y) { 134 virtual void bench(const char name[], int32_t x, int32_t y) {
120 SkString sk_name(name); 135 SkString sk_name(name);
121 sk_name.append("_"); 136 sk_name.append("_");
122 sk_name.appendS32(x); 137 sk_name.appendS32(x);
123 sk_name.append("_"); 138 sk_name.append("_");
124 sk_name.appendS32(y); 139 sk_name.appendS32(y);
125 Json::Value* bench_node = SkFindNamedNode(&fResults, sk_name.c_str()); 140 Json::Value* bench_node = SkFindNamedNode(&fResults, sk_name.c_str());
126 fBench = &(*bench_node)["results"]; 141 fBench = &(*bench_node)["results"];
127 } 142 }
128 virtual void config(const char name[]) { 143 virtual void config(const char name[]) {
129 SkASSERT(NULL != fBench); 144 SkASSERT(NULL != fBench);
130 fConfig = SkFindNamedNode(fBench, name); 145 fConfig = SkFindNamedNode(fBench, name);
131 } 146 }
147 virtual void configOption(const char name[], const char* value) {
148 }
132 virtual void timer(const char name[], double ms) { 149 virtual void timer(const char name[], double ms) {
133 SkASSERT(NULL != fConfig); 150 SkASSERT(NULL != fConfig);
134 (*fConfig)[name] = ms; 151 (*fConfig)[name] = ms;
135 } 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
169 format:
170
171 {
172 "key": {
173 "arch": "Arm7",
174 "gpu": "SGX540",
175 "os": "Android",
176 "model": "GalaxyNexus",
177 }
178 "options": {
179 "GL_Version": "3.1",
180 ...
181 },
182 "gitHash": "d1830323662ae8ae06908b97f15180fd25808894",
183 "results" : {
184 "Xfermode_Luminosity_640_480" : {
185 "8888" : {
186 "median_ms" : 143.188128906250,
187 "min_ms" : 143.835957031250,
188 ...
189 },
190 ...
191 */
192 class NanoJSONResultsWriter : public ResultsWriter {
193 public:
194 explicit NanoJSONResultsWriter(const char filename[], const char gitHash[])
195 : fFilename(filename)
196 , fRoot()
197 , fResults(fRoot["results"])
198 , fBench(NULL)
199 , fConfig(NULL) {
200 fRoot["gitHash"] = gitHash;
201 }
202 virtual void key(const char name[], const char value[]) {
203 fRoot["key"][name] = value;
204 }
205 virtual void option(const char name[], const char value[]) {
206 fRoot["options"][name] = value;
207 }
208 virtual void bench(const char name[], int32_t x, int32_t y) {
209 SkString id = SkStringPrintf( "%s_%d_%d", name, x, y);
210 fResults[id.c_str()] = Json::Value(Json::objectValue);
211 fBench = &fResults[id.c_str()];
212 }
213 virtual void config(const char name[]) {
214 SkASSERT(NULL != fBench);
215 fConfig = &(*fBench)[name];
216 }
217 virtual void configOption(const char name[], const char* value) {
218 (*fConfig)["options"][name] = value;
219 }
220 virtual void timer(const char name[], double ms) {
221 // Don't record if nan, or -nan.
222 if (sk_double_isnan(ms)) {
223 return;
224 }
225 SkASSERT(NULL != fConfig);
226 (*fConfig)[name] = ms;
227 }
136 virtual void end() { 228 virtual void end() {
137 SkFILEWStream stream(fFilename.c_str()); 229 SkFILEWStream stream(fFilename.c_str());
138 stream.writeText(Json::FastWriter().write(fRoot).c_str()); 230 stream.writeText(Json::FastWriter().write(fRoot).c_str());
139 stream.flush(); 231 stream.flush();
140 } 232 }
141 private: 233 private:
142 234
143 SkString fFilename; 235 SkString fFilename;
144 Json::Value fRoot; 236 Json::Value fRoot;
145 Json::Value& fResults; 237 Json::Value& fResults;
146 Json::Value* fBench; 238 Json::Value* fBench;
147 Json::Value* fConfig; 239 Json::Value* fConfig;
148 }; 240 };
149 241
242
150 /** 243 /**
151 * This ResultsWriter writes out to multiple ResultsWriters. 244 * This ResultsWriter writes out to multiple ResultsWriters.
152 */ 245 */
153 class MultiResultsWriter : public ResultsWriter { 246 class MultiResultsWriter : public ResultsWriter {
154 public: 247 public:
155 MultiResultsWriter() : writers() { 248 MultiResultsWriter() : writers() {
156 }; 249 };
157 void add(ResultsWriter* writer) { 250 void add(ResultsWriter* writer) {
158 writers.push_back(writer); 251 writers.push_back(writer);
159 } 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 }
160 virtual void option(const char name[], const char value[]) { 258 virtual void option(const char name[], const char value[]) {
161 for (int i = 0; i < writers.count(); ++i) { 259 for (int i = 0; i < writers.count(); ++i) {
162 writers[i]->option(name, value); 260 writers[i]->option(name, value);
163 } 261 }
164 } 262 }
165 virtual void bench(const char name[], int32_t x, int32_t y) { 263 virtual void bench(const char name[], int32_t x, int32_t y) {
166 for (int i = 0; i < writers.count(); ++i) { 264 for (int i = 0; i < writers.count(); ++i) {
167 writers[i]->bench(name, x, y); 265 writers[i]->bench(name, x, y);
168 } 266 }
169 } 267 }
170 virtual void config(const char name[]) { 268 virtual void config(const char name[]) {
171 for (int i = 0; i < writers.count(); ++i) { 269 for (int i = 0; i < writers.count(); ++i) {
172 writers[i]->config(name); 270 writers[i]->config(name);
173 } 271 }
174 } 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 }
175 virtual void timer(const char name[], double ms) { 278 virtual void timer(const char name[], double ms) {
176 for (int i = 0; i < writers.count(); ++i) { 279 for (int i = 0; i < writers.count(); ++i) {
177 writers[i]->timer(name, ms); 280 writers[i]->timer(name, ms);
178 } 281 }
179 } 282 }
180 virtual void end() { 283 virtual void end() {
181 for (int i = 0; i < writers.count(); ++i) { 284 for (int i = 0; i < writers.count(); ++i) {
182 writers[i]->end(); 285 writers[i]->end();
183 } 286 }
184 } 287 }
185 private: 288 private:
186 SkTArray<ResultsWriter *> writers; 289 SkTArray<ResultsWriter *> writers;
187 }; 290 };
188 291
189 /** 292 /**
190 * Calls the end() method of T on destruction. 293 * Calls the end() method of T on destruction.
191 */ 294 */
192 template <typename T> class CallEnd : SkNoncopyable { 295 template <typename T> class CallEnd : SkNoncopyable {
193 public: 296 public:
194 CallEnd(T& obj) : fObj(obj) {} 297 CallEnd(T& obj) : fObj(obj) {}
195 ~CallEnd() { fObj.end(); } 298 ~CallEnd() { fObj.end(); }
196 private: 299 private:
197 T& fObj; 300 T& fObj;
198 }; 301 };
199 302
200 #endif 303 #endif
OLDNEW
« no previous file with comments | « no previous file | bench/nanobench.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698