aboutsummaryrefslogtreecommitdiffhomepage
path: root/bench/ResultsWriter.h
diff options
context:
space:
mode:
Diffstat (limited to 'bench/ResultsWriter.h')
-rw-r--r--bench/ResultsWriter.h186
1 files changed, 186 insertions, 0 deletions
diff --git a/bench/ResultsWriter.h b/bench/ResultsWriter.h
new file mode 100644
index 0000000000..29d3d1df41
--- /dev/null
+++ b/bench/ResultsWriter.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Classes for writing out bench results in various formats.
+ */
+#ifndef SkResultsWriter_DEFINED
+#define SkResultsWriter_DEFINED
+
+#include "SkBenchLogger.h"
+#include "SkJSONCPP.h"
+#include "SkStream.h"
+#include "SkString.h"
+#include "SkTArray.h"
+#include "SkTypes.h"
+
+
+/**
+ * Base class for writing out the bench results.
+ *
+ * TODO(jcgregorio) Add info if tests fail to converge?
+ */
+class ResultsWriter : SkNoncopyable {
+public:
+ virtual ~ResultsWriter() {};
+
+ // Records one option set for this run. All options must be set before
+ // calling bench().
+ virtual void option(const char name[], const char value[]) = 0;
+
+ // Denotes the start of a specific benchmark. Once bench is called,
+ // then config and timer can be called multiple times to record runs.
+ virtual void bench(const char name[], int32_t x, int32_t y) = 0;
+
+ // Records the specific configuration a bench is run under, such as "8888".
+ virtual void config(const char name[]) = 0;
+
+ // Records a single test metric.
+ virtual void timer(const char name[], double ms) = 0;
+
+ // Call when all results are finished.
+ virtual void end() = 0;
+};
+
+/**
+ * This ResultsWriter handles writing out the human readable format of the
+ * bench results.
+ */
+class LoggerResultsWriter : public ResultsWriter {
+public:
+ explicit LoggerResultsWriter(SkBenchLogger& logger, const char* timeFormat)
+ : fLogger(logger)
+ , fTimeFormat(timeFormat) {
+ fLogger.logProgress("skia bench:");
+ }
+ virtual void option(const char name[], const char value[]) {
+ fLogger.logProgress(SkStringPrintf(" %s=%s", name, value));
+ }
+ virtual void bench(const char name[], int32_t x, int32_t y) {
+ fLogger.logProgress(SkStringPrintf(
+ "\nrunning bench [%3d %3d] %40s", x, y, name));
+ }
+ virtual void config(const char name[]) {
+ fLogger.logProgress(SkStringPrintf(" %s:", name));
+ }
+ virtual void timer(const char name[], double ms) {
+ fLogger.logProgress(SkStringPrintf(" %s = ", name));
+ fLogger.logProgress(SkStringPrintf(fTimeFormat, ms));
+ }
+ virtual void end() {
+ fLogger.logProgress("\n");
+ }
+private:
+ SkBenchLogger& fLogger;
+ const char* fTimeFormat;
+};
+
+/**
+ * This ResultsWriter handles writing out the results in JSON.
+ *
+ * The output looks like:
+ *
+ * {
+ * "options" : {
+ * "alpha" : "0xFF",
+ * "scale" : "0",
+ * ...
+ * "system" : "UNIX"
+ * },
+ * "results" : {
+ * "Xfermode_Luminosity_640_480" : {
+ * "565" : {
+ * "cmsecs" : 143.188128906250,
+ * "msecs" : 143.835957031250
+ * },
+ * ...
+ */
+class JSONResultsWriter : public ResultsWriter {
+public:
+ explicit JSONResultsWriter(const char filename[])
+ : fFilename(filename)
+ , fRoot()
+ , fResults(fRoot["results"])
+ , fBench(NULL)
+ , fConfig(NULL) {
+ }
+ virtual void option(const char name[], const char value[]) {
+ fRoot["options"][name] = value;
+ }
+ virtual void bench(const char name[], int32_t x, int32_t y) {
+ fBench = &fResults[SkStringPrintf( "%s_%d_%d", name, x, y).c_str()];
+ }
+ virtual void config(const char name[]) {
+ SkASSERT(NULL != fBench);
+ fConfig = &(*fBench)[name];
+ }
+ virtual void timer(const char name[], double ms) {
+ SkASSERT(NULL != fConfig);
+ (*fConfig)[name] = ms;
+ }
+ virtual void end() {
+ SkFILEWStream stream(fFilename.c_str());
+ stream.writeText(fRoot.toStyledString().c_str());
+ stream.flush();
+ }
+private:
+ SkString fFilename;
+ Json::Value fRoot;
+ Json::Value& fResults;
+ Json::Value* fBench;
+ Json::Value* fConfig;
+};
+
+/**
+ * This ResultsWriter writes out to multiple ResultsWriters.
+ */
+class MultiResultsWriter : public ResultsWriter {
+public:
+ MultiResultsWriter() : writers() {
+ };
+ void add(ResultsWriter* writer) {
+ writers.push_back(writer);
+ }
+ virtual void option(const char name[], const char value[]) {
+ for (int i = 0; i < writers.count(); ++i) {
+ writers[i]->option(name, value);
+ }
+ }
+ virtual void bench(const char name[], int32_t x, int32_t y) {
+ for (int i = 0; i < writers.count(); ++i) {
+ writers[i]->bench(name, x, y);
+ }
+ }
+ virtual void config(const char name[]) {
+ for (int i = 0; i < writers.count(); ++i) {
+ writers[i]->config(name);
+ }
+ }
+ virtual void timer(const char name[], double ms) {
+ for (int i = 0; i < writers.count(); ++i) {
+ writers[i]->timer(name, ms);
+ }
+ }
+ virtual void end() {
+ for (int i = 0; i < writers.count(); ++i) {
+ writers[i]->end();
+ }
+ }
+private:
+ SkTArray<ResultsWriter *> writers;
+};
+
+/**
+ * Calls the end() method of T on destruction.
+ */
+template <typename T> class CallEnd : SkNoncopyable {
+public:
+ CallEnd(T& obj) : fObj(obj) {}
+ ~CallEnd() { fObj.end(); }
+private:
+ T& fObj;
+};
+
+#endif