2 * Copyright 2013 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
7 * Classes for writing out bench results in various formats.
9 #ifndef SkResultsWriter_DEFINED
10 #define SkResultsWriter_DEFINED
12 #include "SkBenchLogger.h"
13 #include "SkJSONCPP.h"
21 * Base class for writing out the bench results.
23 * TODO(jcgregorio) Add info if tests fail to converge?
25 class ResultsWriter : SkNoncopyable {
27 virtual ~ResultsWriter() {};
29 // Records one option set for this run. All options must be set before
31 virtual void option(const char name[], const char value[]) = 0;
33 // Denotes the start of a specific benchmark. Once bench is called,
34 // 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;
37 // Records the specific configuration a bench is run under, such as "8888".
38 virtual void config(const char name[]) = 0;
40 // Records a single test metric.
41 virtual void timer(const char name[], double ms) = 0;
43 // Call when all results are finished.
44 virtual void end() = 0;
48 * This ResultsWriter handles writing out the human readable format of the
51 class LoggerResultsWriter : public ResultsWriter {
53 explicit LoggerResultsWriter(SkBenchLogger& logger, const char* timeFormat)
55 , fTimeFormat(timeFormat) {
56 fLogger.logProgress("skia bench:");
58 virtual void option(const char name[], const char value[]) {
59 fLogger.logProgress(SkStringPrintf(" %s=%s", name, value));
61 virtual void bench(const char name[], int32_t x, int32_t y) {
62 fLogger.logProgress(SkStringPrintf(
63 "\nrunning bench [%3d %3d] %40s", x, y, name));
65 virtual void config(const char name[]) {
66 fLogger.logProgress(SkStringPrintf(" %s:", name));
68 virtual void timer(const char name[], double ms) {
69 fLogger.logProgress(SkStringPrintf(" %s = ", name));
70 fLogger.logProgress(SkStringPrintf(fTimeFormat, ms));
73 fLogger.logProgress("\n");
76 SkBenchLogger& fLogger;
77 const char* fTimeFormat;
80 #ifdef SK_BUILD_JSON_WRITER
82 * This ResultsWriter handles writing out the results in JSON.
84 * The output looks like:
94 * "Xfermode_Luminosity_640_480" : {
96 * "cmsecs" : 143.188128906250,
97 * "msecs" : 143.835957031250
101 class JSONResultsWriter : public ResultsWriter {
103 explicit JSONResultsWriter(const char filename[])
104 : fFilename(filename)
106 , fResults(fRoot["results"])
110 virtual void option(const char name[], const char value[]) {
111 fRoot["options"][name] = value;
113 virtual void bench(const char name[], int32_t x, int32_t y) {
114 fBench = &fResults[SkStringPrintf( "%s_%d_%d", name, x, y).c_str()];
116 virtual void config(const char name[]) {
117 SkASSERT(NULL != fBench);
118 fConfig = &(*fBench)[name];
120 virtual void timer(const char name[], double ms) {
121 SkASSERT(NULL != fConfig);
122 (*fConfig)[name] = ms;
125 SkFILEWStream stream(fFilename.c_str());
126 stream.writeText(fRoot.toStyledString().c_str());
132 Json::Value& fResults;
134 Json::Value* fConfig;
137 #endif // SK_BUILD_JSON_WRITER
139 * This ResultsWriter writes out to multiple ResultsWriters.
141 class MultiResultsWriter : public ResultsWriter {
143 MultiResultsWriter() : writers() {
145 void add(ResultsWriter* writer) {
146 writers.push_back(writer);
148 virtual void option(const char name[], const char value[]) {
149 for (int i = 0; i < writers.count(); ++i) {
150 writers[i]->option(name, value);
153 virtual void bench(const char name[], int32_t x, int32_t y) {
154 for (int i = 0; i < writers.count(); ++i) {
155 writers[i]->bench(name, x, y);
158 virtual void config(const char name[]) {
159 for (int i = 0; i < writers.count(); ++i) {
160 writers[i]->config(name);
163 virtual void timer(const char name[], double ms) {
164 for (int i = 0; i < writers.count(); ++i) {
165 writers[i]->timer(name, ms);
169 for (int i = 0; i < writers.count(); ++i) {
174 SkTArray<ResultsWriter *> writers;
178 * Calls the end() method of T on destruction.
180 template <typename T> class CallEnd : SkNoncopyable {
182 CallEnd(T& obj) : fObj(obj) {}
183 ~CallEnd() { fObj.end(); }