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// __ _ _______ __ _ _____ ______ _______ __ _ _______ _ _2// | \ | |_____| | \ | | | |_____] |______ | \ | | |_____|3// | \_| | | | \_| |_____| |_____] |______ | \_| |_____ | |4//5// Microbenchmark framework for C++11/14/17/206// https://github.com/martinus/nanobench7//8// Licensed under the MIT License <http://opensource.org/licenses/MIT>.9// SPDX-License-Identifier: MIT10// Copyright (c) 2019-2023 Martin Leitner-Ankerl <[email protected]>11//12// Permission is hereby granted, free of charge, to any person obtaining a copy13// of this software and associated documentation files (the "Software"), to deal14// in the Software without restriction, including without limitation the rights15// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell16// copies of the Software, and to permit persons to whom the Software is17// furnished to do so, subject to the following conditions:18//19// The above copyright notice and this permission notice shall be included in all20// copies or substantial portions of the Software.21//22// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR23// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,24// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE25// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER26// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,27// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE28// SOFTWARE.30#ifndef ANKERL_NANOBENCH_H_INCLUDED31#define ANKERL_NANOBENCH_H_INCLUDED33// see https://semver.org/34#define ANKERL_NANOBENCH_VERSION_MAJOR 4 // incompatible API changes35#define ANKERL_NANOBENCH_VERSION_MINOR 3 // backwards-compatible changes36#define ANKERL_NANOBENCH_VERSION_PATCH 11 // backwards-compatible bug fixes38///////////////////////////////////////////////////////////////////////////////////////////////////39// public facing api - as minimal as possible40///////////////////////////////////////////////////////////////////////////////////////////////////42#include <chrono> // high_resolution_clock43#include <cassert> // assert44#include <cstdint>45#include <cstring> // memcpy46// IWYU will only see this header with ANKERL_NANOBENCH_IMPLEMENT defined, which47// makes it suggest removing forward declarations for the Input/output library.48// IWYU pragma: begin_keep49#include <iosfwd> // for std::ostream* custom output target in Config50// IWYU pragma: end_keep51#include <limits>52#include <ratio>53#include <string> // all names54#include <type_traits>55#include <unordered_map> // holds context information of results56#include <utility>57#include <vector> // holds all results59#define ANKERL_NANOBENCH(x) ANKERL_NANOBENCH_PRIVATE_##x()61#define ANKERL_NANOBENCH_PRIVATE_CXX() __cplusplus62#define ANKERL_NANOBENCH_PRIVATE_CXX98() 199711L63#define ANKERL_NANOBENCH_PRIVATE_CXX11() 201103L64#define ANKERL_NANOBENCH_PRIVATE_CXX14() 201402L65#define ANKERL_NANOBENCH_PRIVATE_CXX17() 201703L67#if ANKERL_NANOBENCH(CXX) >= ANKERL_NANOBENCH(CXX17)68# define ANKERL_NANOBENCH_PRIVATE_NODISCARD() [[nodiscard]]69#else70# define ANKERL_NANOBENCH_PRIVATE_NODISCARD()71#endif73#if defined(__clang__)74# define ANKERL_NANOBENCH_PRIVATE_IGNORE_PADDED_PUSH() \75_Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wpadded\"")76# define ANKERL_NANOBENCH_PRIVATE_IGNORE_PADDED_POP() _Pragma("clang diagnostic pop")77#else78# define ANKERL_NANOBENCH_PRIVATE_IGNORE_PADDED_PUSH()79# define ANKERL_NANOBENCH_PRIVATE_IGNORE_PADDED_POP()80#endif82#if defined(__GNUC__)83# define ANKERL_NANOBENCH_PRIVATE_IGNORE_EFFCPP_PUSH() _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Weffc++\"")84# define ANKERL_NANOBENCH_PRIVATE_IGNORE_EFFCPP_POP() _Pragma("GCC diagnostic pop")85#else86# define ANKERL_NANOBENCH_PRIVATE_IGNORE_EFFCPP_PUSH()87# define ANKERL_NANOBENCH_PRIVATE_IGNORE_EFFCPP_POP()88#endif90#if defined(ANKERL_NANOBENCH_LOG_ENABLED)91# include <iostream>92# define ANKERL_NANOBENCH_LOG(x) \93do { \94std::cout << __FUNCTION__ << "@" << __LINE__ << ": " << x << std::endl; \95} while (0)96#else97# define ANKERL_NANOBENCH_LOG(x) \98do { \99} while (0)100#endif102#define ANKERL_NANOBENCH_PRIVATE_PERF_COUNTERS() 0103#if defined(__linux__) && !defined(ANKERL_NANOBENCH_DISABLE_PERF_COUNTERS)104# include <linux/version.h>105# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)106// PERF_COUNT_HW_REF_CPU_CYCLES only available since kernel 3.3107// PERF_FLAG_FD_CLOEXEC since kernel 3.14108# undef ANKERL_NANOBENCH_PRIVATE_PERF_COUNTERS109# define ANKERL_NANOBENCH_PRIVATE_PERF_COUNTERS() 1110# endif111#endif113#if defined(__clang__)114# define ANKERL_NANOBENCH_NO_SANITIZE(...) __attribute__((no_sanitize(__VA_ARGS__)))115#else116# define ANKERL_NANOBENCH_NO_SANITIZE(...)117#endif119#if defined(_MSC_VER)120# define ANKERL_NANOBENCH_PRIVATE_NOINLINE() __declspec(noinline)121#else122# define ANKERL_NANOBENCH_PRIVATE_NOINLINE() __attribute__((noinline))123#endif125// workaround missing "is_trivially_copyable" in g++ < 5.0126// See https://stackoverflow.com/a/31798726/48181127#if defined(__GNUC__) && __GNUC__ < 5128# define ANKERL_NANOBENCH_IS_TRIVIALLY_COPYABLE(...) __has_trivial_copy(__VA_ARGS__)129#else130# define ANKERL_NANOBENCH_IS_TRIVIALLY_COPYABLE(...) std::is_trivially_copyable<__VA_ARGS__>::value131#endif133// noexcept may be missing for std::string.134// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58265135#define ANKERL_NANOBENCH_PRIVATE_NOEXCEPT_STRING_MOVE() std::is_nothrow_move_assignable<std::string>::value137// declarations ///////////////////////////////////////////////////////////////////////////////////139// As definitions follow these declarations within this140// header, IWYU considers some of them redundant and141// suggests removing them. Disable this IWYU behavior.142// IWYU pragma: begin_keep144namespace ankerl {145namespace nanobench {147using Clock = std::conditional<std::chrono::high_resolution_clock::is_steady, std::chrono::high_resolution_clock,148std::chrono::steady_clock>::type;149class Bench;150struct Config;151class Result;152class Rng;153class BigO;155namespace detail {156template <typename SetupOp>157class SetupRunner;158} // namespace detail160/**161* @brief Renders output from a mustache-like template and benchmark results.162*163* The templating facility here is heavily inspired by [mustache - logic-less templates](https://mustache.github.io/).164* It adds a few more features that are necessary to get all of the captured data out of nanobench. Please read the165* excellent [mustache manual](https://mustache.github.io/mustache.5.html) to see what this is all about.166*167* nanobench output has two nested layers, *result* and *measurement*. Here is a hierarchy of the allowed tags:168*169* * `{{#result}}` Marks the begin of the result layer. Whatever comes after this will be instantiated as often as170* a benchmark result is available. Within it, you can use these tags:171*172* * `{{title}}` See Bench::title.173*174* * `{{name}}` Benchmark name, usually directly provided with Bench::run, but can also be set with Bench::name.175*176* * `{{unit}}` Unit, e.g. `byte`. Defaults to `op`, see Bench::unit.177*178* * `{{batch}}` Batch size, see Bench::batch.179*180* * `{{complexityN}}` Value used for asymptotic complexity calculation. See Bench::complexityN.181*182* * `{{epochs}}` Number of epochs, see Bench::epochs.183*184* * `{{clockResolution}}` Accuracy of the clock, i.e. what's the smallest time possible to measure with the clock.185* For modern systems, this can be around 20 ns. This value is automatically determined by nanobench at the first186* benchmark that is run, and used as a static variable throughout the application's runtime.187*188* * `{{clockResolutionMultiple}}` Configuration multiplier for `clockResolution`. See Bench::clockResolutionMultiple.189* This is the target runtime for each measurement (epoch). That means the more accurate your clock is, the faster190* will be the benchmark. Basing the measurement's runtime on the clock resolution is the main reason why nanobench is so fast.191*192* * `{{maxEpochTime}}` Configuration for a maximum time each measurement (epoch) is allowed to take. Note that at least193* a single iteration will be performed, even when that takes longer than maxEpochTime. See Bench::maxEpochTime.194*195* * `{{minEpochTime}}` Minimum epoch time, defaults to 1ms. See Bench::minEpochTime.196*197* * `{{minEpochIterations}}` See Bench::minEpochIterations.198*199* * `{{epochIterations}}` See Bench::epochIterations.200*201* * `{{warmup}}` Number of iterations used before measuring starts. See Bench::warmup.202*203* * `{{relative}}` True or false, depending on the setting you have used. See Bench::relative.204*205* * `{{context(variableName)}}` See Bench::context.206*207* Apart from these tags, it is also possible to use some mathematical operations on the measurement data. The operations208* are of the form `{{command(name)}}`. Currently `name` can be one of `elapsed`, `iterations`. If performance counters209* are available (currently only on current Linux systems), you also have `pagefaults`, `cpucycles`,210* `contextswitches`, `instructions`, `branchinstructions`, and `branchmisses`. All the measures (except `iterations`) are211* provided for a single iteration (so `elapsed` is the time a single iteration took). The following tags are available:212*213* * `{{median(<name>)}}` Calculate median of a measurement data set, e.g. `{{median(elapsed)}}`.214*215* * `{{average(<name>)}}` Average (mean) calculation.216*217* * `{{medianAbsolutePercentError(<name>)}}` Calculates MdAPE, the Median Absolute Percentage Error. The MdAPE is an excellent218* metric for the variation of measurements. It is more robust to outliers than the219* [Mean absolute percentage error (M-APE)](https://en.wikipedia.org/wiki/Mean_absolute_percentage_error).220* @f[221* \mathrm{MdAPE}(e) = \mathrm{med}\{| \frac{e_i - \mathrm{med}\{e\}}{e_i}| \}222* @f]223* E.g. for *elapsed*: First, @f$ \mathrm{med}\{e\} @f$ calculates the median by sorting and then taking the middle element224* of all *elapsed* measurements. This is used to calculate the absolute percentage225* error to this median for each measurement, as in @f$ | \frac{e_i - \mathrm{med}\{e\}}{e_i}| @f$. All these results226* are sorted, and the middle value is chosen as the median absolute percent error.227*228* This measurement is a bit hard to interpret, but it is very robust against outliers. E.g. a value of 5% means that half of the229* measurements deviate less than 5% from the median, and the other deviate more than 5% from the median.230*231* * `{{sum(<name>)}}` Sum of all the measurements. E.g. `{{sum(iterations)}}` will give you the total number of iterations232* measured in this benchmark.233*234* * `{{minimum(<name>)}}` Minimum of all measurements.235*236* * `{{maximum(<name>)}}` Maximum of all measurements.237*238* * `{{sumProduct(<first>, <second>)}}` Calculates the sum of the products of corresponding measures:239* @f[240* \mathrm{sumProduct}(a,b) = \sum_{i=1}^{n}a_i\cdot b_i241* @f]242* E.g. to calculate total runtime of the benchmark, you multiply iterations with elapsed time for each measurement, and243* sum these results up:244* `{{sumProduct(iterations, elapsed)}}`.245*246* * `{{#measurement}}` To access individual measurement results, open the begin tag for measurements.247*248* * `{{elapsed}}` Average elapsed wall clock time per iteration, in seconds.249*250* * `{{iterations}}` Number of iterations in the measurement. The number of iterations will fluctuate due
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.