| /* | |
| * Copyright 2022 Rive | |
| */ | |
| #include "bench.hpp" | |
| #include <chrono> | |
| #include <string.h> | |
| // Run a microbenchmark repeatedly for a few seconds and print the quickest | |
| // time. | |
| #ifdef __EMSCRIPTEN__ | |
| int rive_wasm_main(int argc, const char* const* argv) | |
| #else | |
| int main(int argc, const char** argv) | |
| #endif | |
| { | |
| using namespace std::chrono_literals; | |
| using clock = std::chrono::high_resolution_clock; | |
| // Default flags. | |
| clock::duration benchDuration = 5s; | |
| // Parse flags. | |
| const char* const* arg = argv + 1; | |
| const char* const* endarg = argv + argc; | |
| while (arg + 1 < endarg && *arg[0] == '-') | |
| { | |
| if (!strcmp(*arg, "--duration") || !strcmp(*arg, "-d")) | |
| { | |
| benchDuration = std::chrono::seconds(atoi(arg[1])); | |
| } | |
| arg += 2; | |
| } | |
| // Find the selected benchmark. | |
| Bench::BenchMap& registry = Bench::Registry(); | |
| const char* benchName = arg < endarg ? *arg : ""; | |
| auto benchIter = registry.find(benchName); | |
| if (benchIter == registry.end()) | |
| { | |
| // Print out the usage unless they ran "bench list". | |
| if (arg >= endarg || !!strcmp(*arg, "list")) | |
| { | |
| fprintf(stderr, | |
| "Usage:\n\nbench [--duration <seconds>] <benchmark>\n\n"); | |
| fprintf(stderr, "Benchmarks:\n\n"); | |
| fflush(stderr); | |
| } | |
| // Print out the benchmarks. | |
| for (const auto& [name, constructor] : registry) | |
| { | |
| printf("%s ", name.c_str()); | |
| } | |
| printf("\n"); | |
| fflush(stdout); | |
| return 1; | |
| } | |
| // Run the benchmark. | |
| auto constructor = benchIter->second; | |
| std::unique_ptr<Bench> bench(constructor()); | |
| bench->setup(); | |
| clock::duration minTime = clock::duration::max(); | |
| clock::time_point quitTime = clock::now() + benchDuration; | |
| clock::time_point start, end; | |
| do | |
| { | |
| bench->beforeRun(); | |
| start = clock::now(); | |
| bench->run(); | |
| end = clock::now(); | |
| minTime = std::min(end - start, minTime); | |
| } while (end < quitTime); | |
| #ifdef DEBUG | |
| printf("<time hidden in debug builds> %s\n", benchName); | |
| #else | |
| printf("%.4gms %s\n", | |
| std::chrono::nanoseconds(minTime).count() * 1e-6, | |
| benchName); | |
| #endif | |
| return 0; | |
| } |