Bitcoin Core  22.99.0
P2P Digital Currency
bench.cpp
Go to the documentation of this file.
1 // Copyright (c) 2015-2020 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <bench/bench.h>
6 
8 
9 #include <chrono>
10 #include <fstream>
11 #include <functional>
12 #include <iostream>
13 #include <map>
14 #include <regex>
15 #include <string>
16 #include <vector>
17 
18 using namespace std::chrono_literals;
19 
20 const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
21 
22 namespace {
23 
24 void GenerateTemplateResults(const std::vector<ankerl::nanobench::Result>& benchmarkResults, const std::string& filename, const char* tpl)
25 {
26  if (benchmarkResults.empty() || filename.empty()) {
27  // nothing to write, bail out
28  return;
29  }
30  std::ofstream fout(filename);
31  if (fout.is_open()) {
32  ankerl::nanobench::render(tpl, benchmarkResults, fout);
33  } else {
34  std::cout << "Could write to file '" << filename << "'" << std::endl;
35  }
36 
37  std::cout << "Created '" << filename << "'" << std::endl;
38 }
39 
40 } // namespace
41 
43 {
44  static std::map<std::string, BenchFunction> benchmarks_map;
45  return benchmarks_map;
46 }
47 
49 {
50  benchmarks().insert(std::make_pair(name, func));
51 }
52 
54 {
55  std::regex reFilter(args.regex_filter);
56  std::smatch baseMatch;
57 
58  std::vector<ankerl::nanobench::Result> benchmarkResults;
59  for (const auto& p : benchmarks()) {
60  if (!std::regex_match(p.first, baseMatch, reFilter)) {
61  continue;
62  }
63 
64  if (args.is_list_only) {
65  std::cout << p.first << std::endl;
66  continue;
67  }
68 
69  Bench bench;
70  bench.name(p.first);
71  if (args.min_time > 0ms) {
72  // convert to nanos before dividing to reduce rounding errors
73  std::chrono::nanoseconds min_time_ns = args.min_time;
74  bench.minEpochTime(min_time_ns / bench.epochs());
75  }
76 
77  if (args.asymptote.empty()) {
78  p.second(bench);
79  } else {
80  for (auto n : args.asymptote) {
81  bench.complexityN(n);
82  p.second(bench);
83  }
84  std::cout << bench.complexityBigO() << std::endl;
85  }
86 
87  if (!bench.results().empty()) {
88  benchmarkResults.push_back(bench.results().back());
89  }
90  }
91 
92  GenerateTemplateResults(benchmarkResults, args.output_csv, "# Benchmark, evals, iterations, total, min, max, median\n"
93  "{{#result}}{{name}}, {{epochs}}, {{average(iterations)}}, {{sumProduct(iterations, elapsed)}}, {{minimum(elapsed)}}, {{maximum(elapsed)}}, {{median(elapsed)}}\n"
94  "{{/result}}");
95  GenerateTemplateResults(benchmarkResults, args.output_json, ankerl::nanobench::templates::json());
96 }
ankerl::nanobench::render
void render(char const *mustacheTemplate, Bench const &bench, std::ostream &out)
Renders output from a mustache-like template and benchmark results.
benchmark::Args::output_json
std::string output_json
Definition: bench.h:48
setup_common.h
ankerl::nanobench::Bench::name
ANKERL_NANOBENCH(NODISCARD) std Bench & name(char const *benchmarkName)
Name of the benchmark, will be shown in the table row.
benchmark::BenchRunner::RunAll
static void RunAll(const Args &args)
Definition: bench.cpp:53
benchmark::Args::min_time
std::chrono::milliseconds min_time
Definition: bench.h:45
ankerl::nanobench::Bench
Main entry point to nanobench's benchmarking facility.
Definition: nanobench.h:616
benchmark::Args::regex_filter
std::string regex_filter
Definition: bench.h:49
benchmark::BenchFunction
std::function< void(Bench &)> BenchFunction
Definition: bench.h:41
fsbridge::ofstream
fs::ofstream ofstream
Definition: fs.h:228
ankerl::nanobench::Bench::complexityBigO
std::vector< BigO > complexityBigO() const
benchmark::Args
Definition: bench.h:43
benchmark::BenchRunner::benchmarks
static BenchmarkMap & benchmarks()
Definition: bench.cpp:42
bench.h
name
const char * name
Definition: rest.cpp:43
ankerl::nanobench::Bench::minEpochTime
ANKERL_NANOBENCH(NODISCARD) std Bench & minEpochTime(std::chrono::nanoseconds t) noexcept
Minimum time each epoch should take.
ankerl::nanobench::Bench::complexityN
Bench & complexityN(T b) noexcept
Definition: nanobench.h:1214
benchmark::BenchRunner::BenchRunner
BenchRunner(std::string name, BenchFunction func)
Definition: bench.cpp:48
ankerl::nanobench::templates::json
char const * json() noexcept
Template to generate JSON data.
benchmark::Args::asymptote
std::vector< double > asymptote
Definition: bench.h:46
benchmark::BenchRunner::BenchmarkMap
std::map< std::string, BenchFunction > BenchmarkMap
Definition: bench.h:54
ankerl::nanobench::Bench::epochs
Bench & epochs(size_t numEpochs) noexcept
Controls number of epochs, the number of measurements to perform.
benchmark::Args::output_csv
std::string output_csv
Definition: bench.h:47
benchmark::Args::is_list_only
bool is_list_only
Definition: bench.h:44
G_TEST_LOG_FUN
const std::function< void(const std::string &)> G_TEST_LOG_FUN
This is connected to the logger.
Definition: bench.cpp:20