blob: fa0de8a871adbee3b90aa831e58a5b4fdea6ea63 [file] [log] [blame]
mtklein7e602c22016-07-11 11:27:30 -07001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Benchmark.h"
Mike Klein4bc6d8f2016-10-19 13:27:07 -04009#include "OverwriteLine.h"
mtklein7e602c22016-07-11 11:27:30 -070010#include "SkGraphics.h"
mtklein2052f312016-07-12 14:50:28 -070011#include "SkTaskGroup.h"
mtklein7e602c22016-07-11 11:27:30 -070012#include <algorithm>
13#include <chrono>
Mike Kleincc300a12016-10-12 16:25:27 -040014#include <limits>
mtklein7e602c22016-07-11 11:27:30 -070015#include <regex>
Mike Klein645999f2016-09-28 14:00:51 -040016#include <stdlib.h>
mtklein7e602c22016-07-11 11:27:30 -070017#include <string>
18#include <vector>
19
Mike Klein4bc6d8f2016-10-19 13:27:07 -040020
21#if defined(SK_BUILD_FOR_WIN32)
22static const char* kEllipsis = "...";
23#else
24static const char* kEllipsis = "…";
25#endif
26
mtklein7e602c22016-07-11 11:27:30 -070027int main(int argc, char** argv) {
28 SkGraphics::Init();
mtklein2052f312016-07-12 14:50:28 -070029 SkTaskGroup::Enabler enabled;
mtklein7e602c22016-07-11 11:27:30 -070030
31 using clock = std::chrono::high_resolution_clock;
32 using ns = std::chrono::duration<double, std::nano>;
33
34 std::regex pattern;
Mike Klein645999f2016-09-28 14:00:51 -040035 int limit = 2147483647;
36 if (argc > 1) { pattern = argv[1]; }
37 if (argc > 2) { limit = atoi(argv[2]); }
mtklein7e602c22016-07-11 11:27:30 -070038
39 struct Bench {
40 std::unique_ptr<Benchmark> b;
41 std::string name;
42 ns best;
43 };
44 std::vector<Bench> benches;
45
46 for (auto r = BenchRegistry::Head(); r; r = r->next()) {
47 std::unique_ptr<Benchmark> bench{ r->factory()(nullptr) };
48
49 std::string name = bench->getName();
50 if (std::regex_search(name, pattern) &&
51 bench->isSuitableFor(Benchmark::kNonRendering_Backend)) {
52 bench->delayedSetup();
Mike Kleincc300a12016-10-12 16:25:27 -040053 benches.emplace_back(Bench{std::move(bench), name,
54 ns{std::numeric_limits<double>::infinity()}});
mtklein7e602c22016-07-11 11:27:30 -070055 }
56 }
57
Mike Klein645999f2016-09-28 14:00:51 -040058 if (benches.size() == 0) {
Mike Klein4bc6d8f2016-10-19 13:27:07 -040059 SkDebugf("No bench matched.\n");
Mike Klein645999f2016-09-28 14:00:51 -040060 return 1;
61 }
62
mtklein7e602c22016-07-11 11:27:30 -070063 if (benches.size() > 1) {
64 int common_prefix = benches[0].name.size();
65 for (size_t i = 1; i < benches.size(); i++) {
66 int len = std::mismatch(benches[i-1].name.begin(), benches[i-1].name.end(),
67 benches[i-0].name.begin())
68 .first - benches[i-1].name.begin();
69 common_prefix = std::min(common_prefix, len);
70 }
71 std::string prefix = benches[0].name.substr(0, common_prefix);
72 if (common_prefix) {
73 for (auto& bench : benches) {
Mike Klein4bc6d8f2016-10-19 13:27:07 -040074 bench.name.replace(0, common_prefix, kEllipsis);
mtklein7e602c22016-07-11 11:27:30 -070075 }
76 }
77
78 int common_suffix = benches[0].name.size();
79 for (size_t i = 1; i < benches.size(); i++) {
80 int len = std::mismatch(benches[i-1].name.rbegin(), benches[i-1].name.rend(),
81 benches[i-0].name.rbegin())
82 .first - benches[i-1].name.rbegin();
83 common_suffix = std::min(common_suffix, len);
84 }
85 std::string suffix = benches[0].name.substr(benches[0].name.size() - common_suffix);
86 if (common_suffix) {
87 for (auto& bench : benches) {
Mike Klein4bc6d8f2016-10-19 13:27:07 -040088 bench.name.replace(bench.name.size() - common_suffix, common_suffix, kEllipsis);
mtklein7e602c22016-07-11 11:27:30 -070089 }
90 }
91
Mike Klein4bc6d8f2016-10-19 13:27:07 -040092 SkDebugf("%s%s%s\n", prefix.c_str(), kEllipsis, suffix.c_str());
mtklein7e602c22016-07-11 11:27:30 -070093 }
94
95 int samples = 0;
Mike Klein645999f2016-09-28 14:00:51 -040096 while (samples < limit) {
Mike Klein7c6bc462017-01-05 14:08:50 -050097 std::random_shuffle(benches.begin(), benches.end());
mtklein7e602c22016-07-11 11:27:30 -070098 for (auto& bench : benches) {
99 for (int loops = 1; loops < 1000000000;) {
100 bench.b->preDraw(nullptr);
101 auto start = clock::now();
102 bench.b->draw(loops, nullptr);
103 ns elapsed = clock::now() - start;
104 bench.b->postDraw(nullptr);
105
106 if (elapsed < std::chrono::milliseconds{10}) {
107 loops *= 2;
108 continue;
109 }
110
111 bench.best = std::min(bench.best, elapsed / loops);
112 samples++;
113
Mike Kleinef6bbbd2017-01-05 14:23:57 -0500114 struct Result { const char* name; ns best; };
115 std::vector<Result> sorted(benches.size());
116 for (size_t i = 0; i < benches.size(); i++) {
117 sorted[i].name = benches[i].name.c_str();
118 sorted[i].best = benches[i].best;
119 }
120 std::sort(sorted.begin(), sorted.end(), [](const Result& a, const Result& b) {
mtklein7e602c22016-07-11 11:27:30 -0700121 return a.best < b.best;
122 });
Mike Kleinef6bbbd2017-01-05 14:23:57 -0500123
Mike Klein4bc6d8f2016-10-19 13:27:07 -0400124 SkDebugf("%s%d", kSkOverwriteLine, samples);
Mike Kleinef6bbbd2017-01-05 14:23:57 -0500125 for (auto& result : sorted) {
126 if (sorted.size() == 1) {
127 SkDebugf(" %s %gns" , result.name, result.best.count());
mtklein7e602c22016-07-11 11:27:30 -0700128 } else {
Mike Kleinef6bbbd2017-01-05 14:23:57 -0500129 SkDebugf(" %s %.3gx", result.name, result.best / sorted[0].best);
mtklein7e602c22016-07-11 11:27:30 -0700130 }
131 }
mtklein7e602c22016-07-11 11:27:30 -0700132 break;
133 }
134 }
135 }
136
137 return 0;
138}