Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2015-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <bench/bench.h>7#include <test/util/setup_common.h> // IWYU pragma: keep8#include <util/check.h>9#include <util/fs.h>10#include <util/time.h>12#include <compare>13#include <fstream>14#include <functional>15#include <iostream>16#include <regex>17#include <string>18#include <string_view>19#include <utility>20#include <vector>22/**23* Retrieves the available test setup command line arguments that may be used24* in the benchmark. They will be used only if the benchmark utilizes a25* 'BasicTestingSetup' or any child of it.26*/27static std::function<std::vector<const char*>()> g_bench_command_line_args{};28const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS = []() {29return g_bench_command_line_args();30};32/**33* Retrieve the name of the currently in-use benchmark.34* This is applicable only to benchmarks that utilize the unit test35* framework context setup (e.g. ones using 'MakeNoLogFileContext<TestingSetup>()').36* It places the datadir of each benchmark run within their respective benchmark name.37*/38static std::string g_running_benchmark_name;39const std::function<std::string()> G_TEST_GET_FULL_NAME = []() {40return g_running_benchmark_name;41};43namespace {45void GenerateTemplateResults(const std::vector<ankerl::nanobench::Result>& benchmarkResults, const fs::path& file, const char* tpl)46{47if (benchmarkResults.empty() || file.empty()) {48// nothing to write, bail out49return;50}51std::ofstream fout{file.std_path()};52if (fout.is_open()) {53ankerl::nanobench::render(tpl, benchmarkResults, fout);54std::cout << "Created " << file << std::endl;55} else {56std::cout << "Could not write to file " << file << std::endl;57}58}60} // namespace62namespace benchmark {64BenchRunner::BenchmarkMap& BenchRunner::benchmarks()65{66static BenchmarkMap benchmarks_map;67return benchmarks_map;68}70BenchRunner::BenchRunner(std::string_view name, BenchFunction func)71{72Assert(benchmarks().try_emplace(std::string{name}, std::move(func)).second);73}75void BenchRunner::RunAll(const Args& args)76{77std::regex reFilter(args.regex_filter);78std::smatch baseMatch;80if (args.sanity_check) {81std::cout << "Running with -sanity-check option, output is being suppressed as benchmark results will be useless." << std::endl;82}84// Load inner test setup args85g_bench_command_line_args = [&args]() {86std::vector<const char*> ret;87ret.reserve(args.setup_args.size());88for (const auto& arg : args.setup_args) ret.emplace_back(arg.c_str());89return ret;90};92std::vector<ankerl::nanobench::Result> benchmarkResults;93for (const auto& [name, func] : benchmarks()) {95if (!std::regex_match(name, baseMatch, reFilter)) {96continue;97}99if (args.is_list_only) {100std::cout << name << std::endl;101continue;102}104Bench bench;105if (args.sanity_check) {106bench.epochs(1).epochIterations(1);107bench.output(nullptr);108}109bench.name(name);110g_running_benchmark_name = name;111if (args.min_time > 0ms) {112// convert to nanos before dividing to reduce rounding errors113std::chrono::nanoseconds min_time_ns = args.min_time;114bench.minEpochTime(min_time_ns / bench.epochs());115}117if (args.asymptote.empty()) {118func(bench);119} else {120for (auto n : args.asymptote) {121bench.complexityN(n);122func(bench);123}124std::cout << bench.complexityBigO() << std::endl;125}127if (!bench.results().empty()) {128benchmarkResults.push_back(bench.results().back());129}130}132GenerateTemplateResults(benchmarkResults, args.output_csv, "# Benchmark, evals, iterations, total, min, max, median\n"133"{{#result}}{{name}}, {{epochs}}, {{average(iterations)}}, {{sumProduct(iterations, elapsed)}}, {{minimum(elapsed)}}, {{maximum(elapsed)}}, {{median(elapsed)}}\n"134"{{/result}}");135GenerateTemplateResults(benchmarkResults, args.output_json, ankerl::nanobench::templates::json());136}138} // namespace benchmark
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.