| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 1 | /* | 
 | 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 Klein | 4bc6d8f | 2016-10-19 13:27:07 -0400 | [diff] [blame] | 9 | #include "OverwriteLine.h" | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 10 | #include "SkGraphics.h" | 
| mtklein | 2052f31 | 2016-07-12 14:50:28 -0700 | [diff] [blame] | 11 | #include "SkTaskGroup.h" | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 12 | #include <algorithm> | 
 | 13 | #include <chrono> | 
| Mike Klein | cc300a1 | 2016-10-12 16:25:27 -0400 | [diff] [blame] | 14 | #include <limits> | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 15 | #include <regex> | 
| Mike Klein | 645999f | 2016-09-28 14:00:51 -0400 | [diff] [blame] | 16 | #include <stdlib.h> | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 17 | #include <string> | 
 | 18 | #include <vector> | 
 | 19 |  | 
| Mike Klein | 4bc6d8f | 2016-10-19 13:27:07 -0400 | [diff] [blame] | 20 |  | 
 | 21 | #if defined(SK_BUILD_FOR_WIN32) | 
 | 22 | static const char* kEllipsis = "..."; | 
 | 23 | #else | 
 | 24 | static const char* kEllipsis = "…"; | 
 | 25 | #endif | 
 | 26 |  | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 27 | int main(int argc, char** argv) { | 
 | 28 |     SkGraphics::Init(); | 
| mtklein | 2052f31 | 2016-07-12 14:50:28 -0700 | [diff] [blame] | 29 |     SkTaskGroup::Enabler enabled; | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 30 |  | 
 | 31 |     using clock = std::chrono::high_resolution_clock; | 
 | 32 |     using ns = std::chrono::duration<double, std::nano>; | 
 | 33 |  | 
 | 34 |     std::regex pattern; | 
| Mike Klein | 645999f | 2016-09-28 14:00:51 -0400 | [diff] [blame] | 35 |     int limit = 2147483647; | 
 | 36 |     if (argc > 1) { pattern = argv[1]; } | 
 | 37 |     if (argc > 2) { limit = atoi(argv[2]); } | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 38 |  | 
 | 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 Klein | cc300a1 | 2016-10-12 16:25:27 -0400 | [diff] [blame] | 53 |             benches.emplace_back(Bench{std::move(bench), name, | 
 | 54 |                                        ns{std::numeric_limits<double>::infinity()}}); | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 55 |         } | 
 | 56 |     } | 
 | 57 |  | 
| Mike Klein | 645999f | 2016-09-28 14:00:51 -0400 | [diff] [blame] | 58 |     if (benches.size() == 0) { | 
| Mike Klein | 4bc6d8f | 2016-10-19 13:27:07 -0400 | [diff] [blame] | 59 |         SkDebugf("No bench matched.\n"); | 
| Mike Klein | 645999f | 2016-09-28 14:00:51 -0400 | [diff] [blame] | 60 |         return 1; | 
 | 61 |     } | 
 | 62 |  | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 63 |     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 Klein | 4bc6d8f | 2016-10-19 13:27:07 -0400 | [diff] [blame] | 74 |                 bench.name.replace(0, common_prefix, kEllipsis); | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 75 |             } | 
 | 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 Klein | 4bc6d8f | 2016-10-19 13:27:07 -0400 | [diff] [blame] | 88 |                 bench.name.replace(bench.name.size() - common_suffix, common_suffix, kEllipsis); | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 89 |             } | 
 | 90 |         } | 
 | 91 |  | 
| Mike Klein | 4bc6d8f | 2016-10-19 13:27:07 -0400 | [diff] [blame] | 92 |         SkDebugf("%s%s%s\n", prefix.c_str(), kEllipsis, suffix.c_str()); | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 93 |     } | 
 | 94 |  | 
 | 95 |     int samples = 0; | 
| Mike Klein | 645999f | 2016-09-28 14:00:51 -0400 | [diff] [blame] | 96 |     while (samples < limit) { | 
| Mike Klein | 7c6bc46 | 2017-01-05 14:08:50 -0500 | [diff] [blame] | 97 |         std::random_shuffle(benches.begin(), benches.end()); | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 98 |         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 Klein | ef6bbbd | 2017-01-05 14:23:57 -0500 | [diff] [blame] | 114 |                 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) { | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 121 |                     return a.best < b.best; | 
 | 122 |                 }); | 
| Mike Klein | ef6bbbd | 2017-01-05 14:23:57 -0500 | [diff] [blame] | 123 |  | 
| Mike Klein | 4bc6d8f | 2016-10-19 13:27:07 -0400 | [diff] [blame] | 124 |                 SkDebugf("%s%d", kSkOverwriteLine, samples); | 
| Mike Klein | ef6bbbd | 2017-01-05 14:23:57 -0500 | [diff] [blame] | 125 |                 for (auto& result : sorted) { | 
 | 126 |                     if (sorted.size() == 1) { | 
 | 127 |                         SkDebugf("  %s %gns" , result.name, result.best.count()); | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 128 |                     } else { | 
| Mike Klein | ef6bbbd | 2017-01-05 14:23:57 -0500 | [diff] [blame] | 129 |                         SkDebugf("  %s %.3gx", result.name, result.best / sorted[0].best); | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 130 |                     } | 
 | 131 |                 } | 
| mtklein | 7e602c2 | 2016-07-11 11:27:30 -0700 | [diff] [blame] | 132 |                 break; | 
 | 133 |             } | 
 | 134 |         } | 
 | 135 |     } | 
 | 136 |  | 
 | 137 |     return 0; | 
 | 138 | } |