skia2/tools/monobench.cpp

115 lines
3.7 KiB
C++

/*
* 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;
}