1 // Copyright (c) 2015-2017 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.
5 #include <bench/bench.h>
6 #include <bench/perf.h>
15 void benchmark::ConsolePrinter::header()
17 std::cout
<< "# Benchmark, evals, iterations, total, min, max, median" << std::endl
;
20 void benchmark::ConsolePrinter::result(const State
& state
)
22 auto results
= state
.m_elapsed_results
;
23 std::sort(results
.begin(), results
.end());
25 double total
= state
.m_num_iters
* std::accumulate(results
.begin(), results
.end(), 0.0);
31 if (!results
.empty()) {
32 front
= results
.front();
33 back
= results
.back();
35 size_t mid
= results
.size() / 2;
36 median
= results
[mid
];
37 if (0 == results
.size() % 2) {
38 median
= (results
[mid
] + results
[mid
+ 1]) / 2;
42 std::cout
<< std::setprecision(6);
43 std::cout
<< state
.m_name
<< ", " << state
.m_num_evals
<< ", " << state
.m_num_iters
<< ", " << total
<< ", " << front
<< ", " << back
<< ", " << median
<< std::endl
;
46 void benchmark::ConsolePrinter::footer() {}
47 benchmark::PlotlyPrinter::PlotlyPrinter(std::string plotly_url
, int64_t width
, int64_t height
)
48 : m_plotly_url(plotly_url
), m_width(width
), m_height(height
)
52 void benchmark::PlotlyPrinter::header()
54 std::cout
<< "<html><head>"
55 << "<script src=\"" << m_plotly_url
<< "\"></script>"
56 << "</head><body><div id=\"myDiv\" style=\"width:" << m_width
<< "px; height:" << m_height
<< "px\"></div>"
57 << "<script> var data = ["
61 void benchmark::PlotlyPrinter::result(const State
& state
)
63 std::cout
<< "{ " << std::endl
64 << " name: '" << state
.m_name
<< "', " << std::endl
67 const char* prefix
= "";
68 for (const auto& e
: state
.m_elapsed_results
) {
69 std::cout
<< prefix
<< std::setprecision(6) << e
;
72 std::cout
<< "]," << std::endl
73 << " boxpoints: 'all', jitter: 0.3, pointpos: 0, type: 'box',"
78 void benchmark::PlotlyPrinter::footer()
80 std::cout
<< "]; var layout = { showlegend: false, yaxis: { rangemode: 'tozero', autorange: true } };"
81 << "Plotly.newPlot('myDiv', data, layout);"
82 << "</script></body></html>";
86 benchmark::BenchRunner::BenchmarkMap
& benchmark::BenchRunner::benchmarks()
88 static std::map
<std::string
, Bench
> benchmarks_map
;
89 return benchmarks_map
;
92 benchmark::BenchRunner::BenchRunner(std::string name
, benchmark::BenchFunction func
, uint64_t num_iters_for_one_second
)
94 benchmarks().insert(std::make_pair(name
, Bench
{func
, num_iters_for_one_second
}));
97 void benchmark::BenchRunner::RunAll(Printer
& printer
, uint64_t num_evals
, double scaling
, const std::string
& filter
, bool is_list_only
)
100 if (!std::ratio_less_equal
<benchmark::clock::period
, std::micro
>::value
) {
101 std::cerr
<< "WARNING: Clock precision is worse than microsecond - benchmarks may be less accurate!\n";
104 std::regex
reFilter(filter
);
105 std::smatch baseMatch
;
109 for (const auto& p
: benchmarks()) {
110 if (!std::regex_match(p
.first
, baseMatch
, reFilter
)) {
114 uint64_t num_iters
= static_cast<uint64_t>(p
.second
.num_iters_for_one_second
* scaling
);
115 if (0 == num_iters
) {
118 State
state(p
.first
, num_evals
, num_iters
, printer
);
120 p
.second
.func(state
);
122 printer
.result(state
);
130 bool benchmark::State::UpdateTimer(const benchmark::time_point current_time
)
132 if (m_start_time
!= time_point()) {
133 std::chrono::duration
<double> diff
= current_time
- m_start_time
;
134 m_elapsed_results
.push_back(diff
.count() / m_num_iters
);
136 if (m_elapsed_results
.size() == m_num_evals
) {
141 m_num_iters_left
= m_num_iters
- 1;