aboutsummaryrefslogtreecommitdiffhomepage
path: root/bench/ResultsWriter.h
blob: 56283732ec020f23f39a73d46a2f81d388d96d95 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
 * 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 "BenchLogger.h"
#include "SkJSONCPP.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkTArray.h"
#include "SkTypes.h"

/**
 * Base class for writing out the bench results.
 *
 * Default implementation does nothing.
 */
class ResultsWriter : SkNoncopyable {
public:
    virtual ~ResultsWriter() {}

    // Record one key value pair that makes up a unique key for this type of run, e.g.
    // builder name, machine type, Debug/Release, etc.
    virtual void key(const char name[], const char value[]) {}

    // Record one key value pair that describes the run instance, e.g. git hash, build number.
    virtual void property(const char name[], const char value[]) {}

    // Denote 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) {}

    // Record the specific configuration a bench is run under, such as "8888".
    virtual void config(const char name[]) {}

    // Record the options for a configuration, such as "GL_RENDERER".
    virtual void configOption(const char name[], const char* value) {}

    // Record a single test metric.
    virtual void timer(const char name[], double ms) {}
};

/**
 NanoJSONResultsWriter writes the test results out in the following
 format:

 {
    "key": {
      "arch": "Arm7",
      "gpu": "SGX540",
      "os": "Android",
      "model": "GalaxyNexus",
    }
    "gitHash": "d1830323662ae8ae06908b97f15180fd25808894",
    "build_number": "1234",
    "results" : {
        "Xfermode_Luminosity_640_480" : {
           "8888" : {
                 "median_ms" : 143.188128906250,
                 "min_ms" : 143.835957031250,
                 ...
              },
          ...
*/
class NanoJSONResultsWriter : public ResultsWriter {
public:
    explicit NanoJSONResultsWriter(const char filename[])
        : fFilename(filename)
        , fRoot()
        , fResults(fRoot["results"])
        , fBench(NULL)
        , fConfig(NULL) {}

    ~NanoJSONResultsWriter() {
        SkFILEWStream stream(fFilename.c_str());
        stream.writeText(Json::StyledWriter().write(fRoot).c_str());
        stream.flush();
    }

    // Added under "key".
    virtual void key(const char name[], const char value[]) {
        fRoot["key"][name] = value;
    }
    // Inserted directly into the root.
    virtual void property(const char name[], const char value[]) {
        fRoot[name] = value;
    }
    virtual void bench(const char name[], int32_t x, int32_t y) {
        SkString id = SkStringPrintf( "%s_%d_%d", name, x, y);
        fResults[id.c_str()] = Json::Value(Json::objectValue);
        fBench = &fResults[id.c_str()];
    }
    virtual void config(const char name[]) {
        SkASSERT(NULL != fBench);
        fConfig = &(*fBench)[name];
    }
    virtual void configOption(const char name[], const char* value) {
        (*fConfig)["options"][name] = value;
    }
    virtual void timer(const char name[], double ms) {
        // Don't record if nan, or -nan.
        if (sk_double_isnan(ms)) {
            return;
        }
        SkASSERT(NULL != fConfig);
        (*fConfig)[name] = ms;
    }

private:
    SkString fFilename;
    Json::Value fRoot;
    Json::Value& fResults;
    Json::Value* fBench;
    Json::Value* fConfig;
};


#endif