Index: tools/monobench.cpp |
diff --git a/tools/monobench.cpp b/tools/monobench.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..757e9d38a3d47df54501b1b279de9d316220c054 |
--- /dev/null |
+++ b/tools/monobench.cpp |
@@ -0,0 +1,114 @@ |
+/* |
+ * Copyright 2016 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "Benchmark.h" |
+#include "SkGraphics.h" |
+#include <algorithm> |
+#include <chrono> |
+#include <regex> |
+#include <stdio.h> |
+#include <string> |
+#include <vector> |
+ |
+int main(int argc, char** argv) { |
+ SkGraphics::Init(); |
+ |
+ using clock = std::chrono::high_resolution_clock; |
+ using ns = std::chrono::duration<double, std::nano>; |
+ |
+ std::regex pattern; |
+ if (argc > 1) { |
+ pattern = argv[1]; |
+ } |
+ |
+ struct Bench { |
+ std::unique_ptr<Benchmark> b; |
+ std::string name; |
+ ns best; |
+ }; |
+ std::vector<Bench> benches; |
+ |
+ for (auto r = BenchRegistry::Head(); r; r = r->next()) { |
+ std::unique_ptr<Benchmark> bench{ r->factory()(nullptr) }; |
+ |
+ std::string name = bench->getName(); |
+ if (std::regex_search(name, pattern) && |
+ bench->isSuitableFor(Benchmark::kNonRendering_Backend)) { |
+ bench->delayedSetup(); |
+ benches.emplace_back(Bench{std::move(bench), name, ns{1.0/0.0}}); |
+ } |
+ } |
+ |
+ if (benches.size() > 1) { |
+ int common_prefix = benches[0].name.size(); |
+ for (size_t i = 1; i < benches.size(); i++) { |
+ int len = std::mismatch(benches[i-1].name.begin(), benches[i-1].name.end(), |
+ benches[i-0].name.begin()) |
+ .first - benches[i-1].name.begin(); |
+ common_prefix = std::min(common_prefix, len); |
+ } |
+ std::string prefix = benches[0].name.substr(0, common_prefix); |
+ if (common_prefix) { |
+ for (auto& bench : benches) { |
+ bench.name.replace(0, common_prefix, "…"); |
+ } |
+ } |
+ |
+ int common_suffix = benches[0].name.size(); |
+ for (size_t i = 1; i < benches.size(); i++) { |
+ int len = std::mismatch(benches[i-1].name.rbegin(), benches[i-1].name.rend(), |
+ benches[i-0].name.rbegin()) |
+ .first - benches[i-1].name.rbegin(); |
+ common_suffix = std::min(common_suffix, len); |
+ } |
+ std::string suffix = benches[0].name.substr(benches[0].name.size() - common_suffix); |
+ if (common_suffix) { |
+ for (auto& bench : benches) { |
+ bench.name.replace(bench.name.size() - common_suffix, common_suffix, "…"); |
+ } |
+ } |
+ |
+ printf("%s…%s\n", prefix.c_str(), suffix.c_str()); |
+ } |
+ |
+ int samples = 0; |
+ for (;;) { |
+ for (auto& bench : benches) { |
+ for (int loops = 1; loops < 1000000000;) { |
+ bench.b->preDraw(nullptr); |
+ auto start = clock::now(); |
+ bench.b->draw(loops, nullptr); |
+ ns elapsed = clock::now() - start; |
+ bench.b->postDraw(nullptr); |
+ |
+ if (elapsed < std::chrono::milliseconds{10}) { |
+ loops *= 2; |
+ continue; |
+ } |
+ |
+ bench.best = std::min(bench.best, elapsed / loops); |
+ samples++; |
+ |
+ std::sort(benches.begin(), benches.end(), [](const Bench& a, const Bench& b) { |
+ return a.best < b.best; |
+ }); |
+ printf("\r\033[K%d", samples); |
+ for (auto& bench : benches) { |
+ if (benches.size() == 1) { |
+ printf(" %s %gns" , bench.name.c_str(), bench.best.count()); |
+ } else { |
+ printf(" %s %.3gx", bench.name.c_str(), bench.best / benches[0].best); |
+ } |
+ } |
+ fflush(stdout); |
+ break; |
+ } |
+ } |
+ } |
+ |
+ return 0; |
+} |