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