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.
752/**753* @brief Sets the operation unit.754*755* Defaults to "op". Could be e.g. "byte" for string processing. This is used for the table header, e.g. to show `ns/byte`. Use756* singular (*byte*, not *bytes*). A change clears the currently collected results.757*758* @param unit The unit name.759*/760Bench& unit(char const* unit);761Bench& unit(std::string const& unit);762ANKERL_NANOBENCH(NODISCARD) std::string const& unit() const noexcept;764/**765* @brief Sets the time unit to be used for the default output.766*767* Nanobench defaults to using ns (nanoseconds) as output in the markdown. For some benchmarks this is too coarse, so it is768* possible to configure this. E.g. use `timeUnit(1ms, "ms")` to show `ms/op` instead of `ns/op`.769*770* @param tu Time unit to display the results in, default is 1ns.771* @param tuName Name for the time unit, default is "ns"772*/773Bench& timeUnit(std::chrono::duration<double> const& tu, std::string const& tuName);774ANKERL_NANOBENCH(NODISCARD) std::string const& timeUnitName() const noexcept;775ANKERL_NANOBENCH(NODISCARD) std::chrono::duration<double> const& timeUnit() const noexcept;777/**778* @brief Set the output stream where the resulting markdown table will be printed to.779*780* The default is `&std::cout`. You can disable all output by setting `nullptr`.781*782* @param outstream Pointer to output stream, can be `nullptr`.783*/784Bench& output(std::ostream* outstream) noexcept;785ANKERL_NANOBENCH(NODISCARD) std::ostream* output() const noexcept;787/**788* Modern processors have a very accurate clock, being able to measure as low as 20 nanoseconds. This is the main trick nanobech to789* be so fast: we find out how accurate the clock is, then run the benchmark only so often that the clock's accuracy is good enough790* for accurate measurements.791*792* The default is to run one epoch for 1000 times the clock resolution. So for 20ns resolution and 11 epochs, this gives a total793* runtime of794*795* @f[796* 20ns * 1000 * 11 \approx 0.2ms797* @f]798*799* To be precise, nanobench adds a 0-20% random noise to each evaluation. This is to prevent any aliasing effects, and further800* improves accuracy.801*802* Total runtime will be higher though: Some initial time is needed to find out the target number of iterations for each epoch, and803* there is some overhead involved to start & stop timers and calculate resulting statistics and writing the output.804*805* @param multiple Target number of times of clock resolution. Usually 1000 is a good compromise between runtime and accuracy.806*/807Bench& clockResolutionMultiple(size_t multiple) noexcept;808ANKERL_NANOBENCH(NODISCARD) size_t clockResolutionMultiple() const noexcept;810/**811* @brief Controls number of epochs, the number of measurements to perform.812*813* The reported result will be the median of evaluation of each epoch. The higher you choose this, the more814* deterministic the result be and outliers will be more easily removed. Also the `err%` will be more accurate the higher this815* number is. Note that the `err%` will not necessarily decrease when number of epochs is increased. But it will be a more accurate816* representation of the benchmarked code's runtime stability.817*818* Choose the value wisely. In practice, 11 has been shown to be a reasonable choice between runtime performance and accuracy.819* This setting goes hand in hand with minEpochIterations() (or minEpochTime()). If you are more interested in *median* runtime,820* you might want to increase epochs(). If you are more interested in *mean* runtime, you might want to increase821* minEpochIterations() instead.822*823* @param numEpochs Number of epochs.824*/825Bench& epochs(size_t numEpochs) noexcept;826ANKERL_NANOBENCH(NODISCARD) size_t epochs() const noexcept;828/**829* @brief Upper limit for the runtime of each epoch.830*831* As a safety precaution if the clock is not very accurate, we can set an upper limit for the maximum evaluation time per832* epoch. Default is 100ms. At least a single evaluation of the benchmark is performed.833*834* @see minEpochTime, minEpochIterations835*836* @param t Maximum target runtime for a single epoch.837*/838Bench& maxEpochTime(std::chrono::nanoseconds t) noexcept;839ANKERL_NANOBENCH(NODISCARD) std::chrono::nanoseconds maxEpochTime() const noexcept;841/**842* @brief Minimum time each epoch should take.843*844* Default is 1ms, so we are mostly relying on clockResolutionMultiple(). In most cases this is exactly what you want. If you see845* that the evaluation is unreliable with a high `err%`, you can increase either minEpochTime() or minEpochIterations().846*847* @see maxEpochTime, minEpochIterations848*849* @param t Minimum time each epoch should take.850*/851Bench& minEpochTime(std::chrono::nanoseconds t) noexcept;852ANKERL_NANOBENCH(NODISCARD) std::chrono::nanoseconds minEpochTime() const noexcept;854/**855* @brief Sets the minimum number of iterations each epoch should take.856*857* Default is 1, and we rely on clockResolutionMultiple(). If the `err%` is high and you want a more smooth result, you might want858* to increase the minimum number of iterations, or increase the minEpochTime().859*860* @see minEpochTime, maxEpochTime, minEpochIterations861*862* @param numIters Minimum number of iterations per epoch.863*/864Bench& minEpochIterations(uint64_t numIters) noexcept;865ANKERL_NANOBENCH(NODISCARD) uint64_t minEpochIterations() const noexcept;867/**868* Sets exactly the number of iterations for each epoch. Ignores all other epoch limits. This forces nanobench to use exactly869* the given number of iterations for each epoch, not more and not less. Default is 0 (disabled).870*871* @param numIters Exact number of iterations to use. Set to 0 to disable.872*/873Bench& epochIterations(uint64_t numIters) noexcept;874ANKERL_NANOBENCH(NODISCARD) uint64_t epochIterations() const noexcept;876/**877* @brief Sets a number of iterations that are initially performed without any measurements.878*879* Some benchmarks need a few evaluations to warm up caches / database / whatever access. Normally this should not be needed, since880* we show the median result so initial outliers will be filtered away automatically. If the warmup effect is large though, you881* might want to set it. Default is 0.882*883* @param numWarmupIters Number of warmup iterations.884*/885Bench& warmup(uint64_t numWarmupIters) noexcept;886ANKERL_NANOBENCH(NODISCARD) uint64_t warmup() const noexcept;888/**889* @brief Marks the next run as the baseline.890*891* Call `relative(true)` to mark the run as the baseline. Successive runs will be compared to this run. It is calculated by892*893* @f[894* 100\% * \frac{baseline}{runtime}895* @f]896*897* * 100% means it is exactly as fast as the baseline898* * >100% means it is faster than the baseline. E.g. 200% means the current run is twice as fast as the baseline.899* * <100% means it is slower than the baseline. E.g. 50% means it is twice as slow as the baseline.900*901* See the tutorial section "Comparing Results" for example usage.902*903* @param isRelativeEnabled True to enable processing904*/905Bench& relative(bool isRelativeEnabled) noexcept;906ANKERL_NANOBENCH(NODISCARD) bool relative() const noexcept;908/**909* @brief Enables/disables performance counters.910*911* On Linux nanobench has a powerful feature to use performance counters. This enables counting of retired instructions, count912* number of branches, missed branches, etc. On default this is enabled, but you can disable it if you don't need that feature.913*914* @param showPerformanceCounters True to enable, false to disable.915*/916Bench& performanceCounters(bool showPerformanceCounters) noexcept;917ANKERL_NANOBENCH(NODISCARD) bool performanceCounters() const noexcept;919/**920* @brief Retrieves all benchmark results collected by the bench object so far.921*922* Each call to run() generates a Result that is stored within the Bench instance. This is mostly for advanced users who want to923* see all the nitty gritty details.924*925* @return All results collected so far.926*/927ANKERL_NANOBENCH(NODISCARD) std::vector<Result> const& results() const noexcept;929/*!930@verbatim embed:rst932Convenience shortcut to :cpp:func:`ankerl::nanobench::doNotOptimizeAway`.934@endverbatim935*/936template <typename Arg>937Bench& doNotOptimizeAway(Arg&& arg);939/*!940@verbatim embed:rst942Sets N for asymptotic complexity calculation, so it becomes possible to calculate `Big O943<https://en.wikipedia.org/wiki/Big_O_notation>`_ from multiple benchmark evaluations.945Use :cpp:func:`ankerl::nanobench::Bench::complexityBigO` when the evaluation has finished. See the tutorial946:ref:`asymptotic-complexity` for details.948@endverbatim950@tparam T Any type is cast to `double`.951@param n Length of N for the next benchmark run, so it is possible to calculate `bigO`.952*/953template <typename T>954Bench& complexityN(T n) noexcept;955ANKERL_NANOBENCH(NODISCARD) double complexityN() const noexcept;957/*!958Calculates [Big O](https://en.wikipedia.org/wiki/Big_O_notation>) of the results with all preconfigured complexity functions.959Currently these complexity functions are fitted into the benchmark results:961@f$ \mathcal{O}(1) @f$,962@f$ \mathcal{O}(n) @f$,963@f$ \mathcal{O}(\log{}n) @f$,964@f$ \mathcal{O}(n\log{}n) @f$,965@f$ \mathcal{O}(n^2) @f$,966@f$ \mathcal{O}(n^3) @f$.968If we e.g. evaluate the complexity of `std::sort`, this is the result of `std::cout << bench.complexityBigO()`:970```971| coefficient | err% | complexity972|--------------:|-------:|------------973| 5.08935e-09 | 2.6% | O(n log n)974| 6.10608e-08 | 8.0% | O(n)975| 1.29307e-11 | 47.2% | O(n^2)976| 2.48677e-15 | 69.6% | O(n^3)977| 9.88133e-06 | 132.3% | O(log n)978| 5.98793e-05 | 162.5% | O(1)979```981So in this case @f$ \mathcal{O}(n\log{}n) @f$ provides the best approximation.983@verbatim embed:rst984See the tutorial :ref:`asymptotic-complexity` for details.985@endverbatim986@return Evaluation results, which can be printed or otherwise inspected.987*/988std::vector<BigO> complexityBigO() const;990/**991* @brief Calculates bigO for a custom function.992*993* E.g. to calculate the mean squared error for @f$ \mathcal{O}(\log{}\log{}n) @f$, which is not part of the default set of994* complexityBigO(), you can do this:995*996* ```997* auto logLogN = bench.complexityBigO("O(log log n)", [](double n) {998* return std::log2(std::log2(n));999* });1000* ```
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.