blob: 757e9d38a3d47df54501b1b279de9d316220c054 [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"
9#include "SkGraphics.h"
10#include <algorithm>
11#include <chrono>
12#include <regex>
13#include <stdio.h>
14#include <string>
15#include <vector>
16
17int main(int argc, char** argv) {
18 SkGraphics::Init();
19
20 using clock = std::chrono::high_resolution_clock;
21 using ns = std::chrono::duration<double, std::nano>;
22
23 std::regex pattern;
24 if (argc > 1) {
25 pattern = argv[1];
26 }
27
28 struct Bench {
29 std::unique_ptr<Benchmark> b;
30 std::string name;
31 ns best;
32 };
33 std::vector<Bench> benches;
34
35 for (auto r = BenchRegistry::Head(); r; r = r->next()) {
36 std::unique_ptr<Benchmark> bench{ r->factory()(nullptr) };
37
38 std::string name = bench->getName();
39 if (std::regex_search(name, pattern) &&
40 bench->isSuitableFor(Benchmark::kNonRendering_Backend)) {
41 bench->delayedSetup();
42 benches.emplace_back(Bench{std::move(bench), name, ns{1.0/0.0}});
43 }
44 }
45
46 if (benches.size() > 1) {
47 int common_prefix = benches[0].name.size();
48 for (size_t i = 1; i < benches.size(); i++) {
49 int len = std::mismatch(benches[i-1].name.begin(), benches[i-1].name.end(),
50 benches[i-0].name.begin())
51 .first - benches[i-1].name.begin();
52 common_prefix = std::min(common_prefix, len);
53 }
54 std::string prefix = benches[0].name.substr(0, common_prefix);
55 if (common_prefix) {
56 for (auto& bench : benches) {
57 bench.name.replace(0, common_prefix, "…");
58 }
59 }
60
61 int common_suffix = benches[0].name.size();
62 for (size_t i = 1; i < benches.size(); i++) {
63 int len = std::mismatch(benches[i-1].name.rbegin(), benches[i-1].name.rend(),
64 benches[i-0].name.rbegin())
65 .first - benches[i-1].name.rbegin();
66 common_suffix = std::min(common_suffix, len);
67 }
68 std::string suffix = benches[0].name.substr(benches[0].name.size() - common_suffix);
69 if (common_suffix) {
70 for (auto& bench : benches) {
71 bench.name.replace(bench.name.size() - common_suffix, common_suffix, "…");
72 }
73 }
74
75 printf("%s…%s\n", prefix.c_str(), suffix.c_str());
76 }
77
78 int samples = 0;
79 for (;;) {
80 for (auto& bench : benches) {
81 for (int loops = 1; loops < 1000000000;) {
82 bench.b->preDraw(nullptr);
83 auto start = clock::now();
84 bench.b->draw(loops, nullptr);
85 ns elapsed = clock::now() - start;
86 bench.b->postDraw(nullptr);
87
88 if (elapsed < std::chrono::milliseconds{10}) {
89 loops *= 2;
90 continue;
91 }
92
93 bench.best = std::min(bench.best, elapsed / loops);
94 samples++;
95
96 std::sort(benches.begin(), benches.end(), [](const Bench& a, const Bench& b) {
97 return a.best < b.best;
98 });
99 printf("\r\033[K%d", samples);
100 for (auto& bench : benches) {
101 if (benches.size() == 1) {
102 printf(" %s %gns" , bench.name.c_str(), bench.best.count());
103 } else {
104 printf(" %s %.3gx", bench.name.c_str(), bench.best / benches[0].best);
105 }
106 }
107 fflush(stdout);
108 break;
109 }
110 }
111 }
112
113 return 0;
114}