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 (except compressed to a single line):
95 * "name" : "Xfermode_Luminosity_640_480",
99 * "cmsecs" : 143.188128906250,
100 * "msecs" : 143.835957031250
105 Json::Value* SkFindNamedNode(Json::Value* root, const char name[]);
106 class JSONResultsWriter : public ResultsWriter {
108 explicit JSONResultsWriter(const char filename[])
109 : fFilename(filename)
111 , fResults(fRoot["results"])
115 virtual void option(const char name[], const char value[]) {
116 fRoot["options"][name] = value;
118 virtual void bench(const char name[], int32_t x, int32_t y) {
119 SkString sk_name(name);
121 sk_name.appendS32(x);
123 sk_name.appendS32(y);
124 Json::Value* bench_node = SkFindNamedNode(&fResults, sk_name.c_str());
125 fBench = &(*bench_node)["results"];
127 virtual void config(const char name[]) {
128 SkASSERT(NULL != fBench);
129 fConfig = SkFindNamedNode(fBench, name);
131 virtual void timer(const char name[], double ms) {
132 SkASSERT(NULL != fConfig);
133 (*fConfig)[name] = ms;
136 SkFILEWStream stream(fFilename.c_str());
137 stream.writeText(Json::FastWriter().write(fRoot).c_str());
144 Json::Value& fResults;
146 Json::Value* fConfig;
149 #endif // SK_BUILD_JSON_WRITER
152 * This ResultsWriter writes out to multiple ResultsWriters.
154 class MultiResultsWriter : public ResultsWriter {
156 MultiResultsWriter() : writers() {
158 void add(ResultsWriter* writer) {
159 writers.push_back(writer);
161 virtual void option(const char name[], const char value[]) {
162 for (int i = 0; i < writers.count(); ++i) {
163 writers[i]->option(name, value);
166 virtual void bench(const char name[], int32_t x, int32_t y) {
167 for (int i = 0; i < writers.count(); ++i) {
168 writers[i]->bench(name, x, y);
171 virtual void config(const char name[]) {
172 for (int i = 0; i < writers.count(); ++i) {
173 writers[i]->config(name);
176 virtual void timer(const char name[], double ms) {
177 for (int i = 0; i < writers.count(); ++i) {
178 writers[i]->timer(name, ms);
182 for (int i = 0; i < writers.count(); ++i) {
187 SkTArray<ResultsWriter *> writers;
191 * Calls the end() method of T on destruction.
193 template <typename T> class CallEnd : SkNoncopyable {
195 CallEnd(T& obj) : fObj(obj) {}
196 ~CallEnd() { fObj.end(); }