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.
251* to some applied randomness, to enhance accuracy.252*253* * `{{pagefaults}}` Average number of pagefaults per iteration.254*255* * `{{cpucycles}}` Average number of CPU cycles processed per iteration.256*257* * `{{contextswitches}}` Average number of context switches per iteration.258*259* * `{{instructions}}` Average number of retired instructions per iteration.260*261* * `{{branchinstructions}}` Average number of branches executed per iteration.262*263* * `{{branchmisses}}` Average number of branches that were missed per iteration.264*265* * `{{/measurement}}` Ends the measurement tag.266*267* * `{{/result}}` Marks the end of the result layer. This is the end marker for the template part that will be instantiated268* for each benchmark result.269*270*271* For the layer tags *result* and *measurement* you additionally can use these special markers:272*273* * ``{{#-first}}`` - Begin marker of a template that will be instantiated *only for the first* entry in the layer. Use is only274* allowed between the begin and end marker of the layer. So between ``{{#result}}`` and ``{{/result}}``, or between275* ``{{#measurement}}`` and ``{{/measurement}}``. Finish the template with ``{{/-first}}``.276*277* * ``{{^-first}}`` - Begin marker of a template that will be instantiated *for each except the first* entry in the layer. This,278* this is basically the inversion of ``{{#-first}}``. Use is only allowed between the begin and end marker of the layer.279* So between ``{{#result}}`` and ``{{/result}}``, or between ``{{#measurement}}`` and ``{{/measurement}}``.280*281* * ``{{/-first}}`` - End marker for either ``{{#-first}}`` or ``{{^-first}}``.282*283* * ``{{#-last}}`` - Begin marker of a template that will be instantiated *only for the last* entry in the layer. Use is only284* allowed between the begin and end marker of the layer. So between ``{{#result}}`` and ``{{/result}}``, or between285* ``{{#measurement}}`` and ``{{/measurement}}``. Finish the template with ``{{/-last}}``.286*287* * ``{{^-last}}`` - Begin marker of a template that will be instantiated *for each except the last* entry in the layer. This,288* this is basically the inversion of ``{{#-last}}``. Use is only allowed between the begin and end marker of the layer.289* So between ``{{#result}}`` and ``{{/result}}``, or between ``{{#measurement}}`` and ``{{/measurement}}``.290*291* * ``{{/-last}}`` - End marker for either ``{{#-last}}`` or ``{{^-last}}``.292*293@verbatim embed:rst295For an overview of all the possible data you can get out of nanobench, please see the tutorial at :ref:`tutorial-template-json`.297The templates that ship with nanobench are:299* :cpp:func:`templates::csv() <ankerl::nanobench::templates::csv()>`300* :cpp:func:`templates::json() <ankerl::nanobench::templates::json()>`301* :cpp:func:`templates::htmlBoxplot() <ankerl::nanobench::templates::htmlBoxplot()>`302* :cpp:func:`templates::pyperf() <ankerl::nanobench::templates::pyperf()>`304@endverbatim305*306* @param mustacheTemplate The template.307* @param bench Benchmark, containing all the results.308* @param out Output for the generated output.309*/310void render(char const* mustacheTemplate, Bench const& bench, std::ostream& out);311void render(std::string const& mustacheTemplate, Bench const& bench, std::ostream& out);313/**314* Same as render(char const* mustacheTemplate, Bench const& bench, std::ostream& out), but for when315* you only have results available.316*317* @param mustacheTemplate The template.318* @param results All the results to be used for rendering.319* @param out Output for the generated output.320*/321void render(char const* mustacheTemplate, std::vector<Result> const& results, std::ostream& out);322void render(std::string const& mustacheTemplate, std::vector<Result> const& results, std::ostream& out);324// Contains mustache-like templates325namespace templates {327/*!328@brief CSV data for the benchmark results.330Generates a comma-separated values dataset. First line is the header, each following line is a summary of each benchmark run.332@verbatim embed:rst333See the tutorial at :ref:`tutorial-template-csv` for an example.334@endverbatim335*/336char const* csv() noexcept;338/*!339@brief HTML output that uses plotly to generate an interactive boxplot chart. See the tutorial for an example output.341The output uses only the elapsed wall clock time, and displays each epoch as a single dot.342@verbatim embed:rst343See the tutorial at :ref:`tutorial-template-html` for an example.344@endverbatim346@see also ankerl::nanobench::render()347*/348char const* htmlBoxplot() noexcept;350/*!351@brief Output in pyperf compatible JSON format, which can be used for more analyzation.352@verbatim embed:rst353See the tutorial at :ref:`tutorial-template-pyperf` for an example how to further analyze the output.354@endverbatim355*/356char const* pyperf() noexcept;358/*!359@brief Template to generate JSON data.361The generated JSON data contains *all* data that has been generated. All times are as double values, in seconds. The output can get362quite large.363@verbatim embed:rst364See the tutorial at :ref:`tutorial-template-json` for an example.365@endverbatim366*/367char const* json() noexcept;369} // namespace templates371namespace detail {373template <typename T>374struct PerfCountSet;376class IterationLogic;377class PerformanceCounters;379#if ANKERL_NANOBENCH(PERF_COUNTERS)380class LinuxPerformanceCounters;381#endif383} // namespace detail384} // namespace nanobench385} // namespace ankerl387// IWYU pragma: end_keep389// definitions ////////////////////////////////////////////////////////////////////////////////////391namespace ankerl {392namespace nanobench {393namespace detail {395template <typename T>396struct PerfCountSet {397T pageFaults{};398T cpuCycles{};399T contextSwitches{};400T instructions{};401T branchInstructions{};402T branchMisses{};403};405} // namespace detail407ANKERL_NANOBENCH(IGNORE_PADDED_PUSH)408struct Config {409// actual benchmark config410std::string mBenchmarkTitle = "benchmark"; // NOLINT(misc-non-private-member-variables-in-classes)411std::string mBenchmarkName = "noname"; // NOLINT(misc-non-private-member-variables-in-classes)412std::string mUnit = "op"; // NOLINT(misc-non-private-member-variables-in-classes)413double mBatch = 1.0; // NOLINT(misc-non-private-member-variables-in-classes)414double mComplexityN = -1.0; // NOLINT(misc-non-private-member-variables-in-classes)415size_t mNumEpochs = 11; // NOLINT(misc-non-private-member-variables-in-classes)416size_t mClockResolutionMultiple = static_cast<size_t>(1000); // NOLINT(misc-non-private-member-variables-in-classes)417std::chrono::nanoseconds mMaxEpochTime = std::chrono::milliseconds(100); // NOLINT(misc-non-private-member-variables-in-classes)418std::chrono::nanoseconds mMinEpochTime = std::chrono::milliseconds(1); // NOLINT(misc-non-private-member-variables-in-classes)419uint64_t mMinEpochIterations{1}; // NOLINT(misc-non-private-member-variables-in-classes)420// If not 0, run *exactly* these number of iterations per epoch.421uint64_t mEpochIterations{0}; // NOLINT(misc-non-private-member-variables-in-classes)422uint64_t mWarmup = 0; // NOLINT(misc-non-private-member-variables-in-classes)423std::ostream* mOut = nullptr; // NOLINT(misc-non-private-member-variables-in-classes)424std::chrono::duration<double> mTimeUnit = std::chrono::nanoseconds{1}; // NOLINT(misc-non-private-member-variables-in-classes)425std::string mTimeUnitName = "ns"; // NOLINT(misc-non-private-member-variables-in-classes)426bool mShowPerformanceCounters = true; // NOLINT(misc-non-private-member-variables-in-classes)427bool mIsRelative = false; // NOLINT(misc-non-private-member-variables-in-classes)428std::unordered_map<std::string, std::string> mContext{}; // NOLINT(misc-non-private-member-variables-in-classes)430Config();431~Config();432Config& operator=(Config const& other);433Config& operator=(Config&& other) noexcept(ANKERL_NANOBENCH(NOEXCEPT_STRING_MOVE));434Config(Config const& other);435Config(Config&& other) noexcept;436};437ANKERL_NANOBENCH(IGNORE_PADDED_POP)439// Result returned after a benchmark has finished. Can be used as a baseline for relative().440ANKERL_NANOBENCH(IGNORE_PADDED_PUSH)441class Result {442public:443enum class Measure : size_t {444elapsed,445iterations,446pagefaults,447cpucycles,448contextswitches,449instructions,450branchinstructions,451branchmisses,452_size453};455explicit Result(Config benchmarkConfig);457~Result();458Result& operator=(Result const& other);459Result& operator=(Result&& other) noexcept(ANKERL_NANOBENCH(NOEXCEPT_STRING_MOVE));460Result(Result const& other);461Result(Result&& other) noexcept;463// adds new measurement results464// all values are scaled by iters (except iters...)465void add(Clock::duration totalElapsed, uint64_t iters, detail::PerformanceCounters const& pc);467ANKERL_NANOBENCH(NODISCARD) Config const& config() const noexcept;469ANKERL_NANOBENCH(NODISCARD) double median(Measure m) const;470ANKERL_NANOBENCH(NODISCARD) double medianAbsolutePercentError(Measure m) const;471ANKERL_NANOBENCH(NODISCARD) double average(Measure m) const;472ANKERL_NANOBENCH(NODISCARD) double sum(Measure m) const noexcept;473ANKERL_NANOBENCH(NODISCARD) double sumProduct(Measure m1, Measure m2) const noexcept;474ANKERL_NANOBENCH(NODISCARD) double minimum(Measure m) const noexcept;475ANKERL_NANOBENCH(NODISCARD) double maximum(Measure m) const noexcept;476ANKERL_NANOBENCH(NODISCARD) std::string const& context(char const* variableName) const;477ANKERL_NANOBENCH(NODISCARD) std::string const& context(std::string const& variableName) const;479ANKERL_NANOBENCH(NODISCARD) bool has(Measure m) const noexcept;480ANKERL_NANOBENCH(NODISCARD) double get(size_t idx, Measure m) const;481ANKERL_NANOBENCH(NODISCARD) bool empty() const noexcept;482ANKERL_NANOBENCH(NODISCARD) size_t size() const noexcept;484// Finds string, if not found, returns _size.485static Measure fromString(std::string const& str);487private:488Config mConfig{};489std::vector<std::vector<double>> mNameToMeasurements{};490};491ANKERL_NANOBENCH(IGNORE_PADDED_POP)493/**494* An extremely fast random generator. Currently, this implements *RomuDuoJr*, developed by Mark Overton. Source:495* http://www.romu-random.org/496*497* RomuDuoJr is extremely fast and provides reasonable good randomness. Not enough for large jobs, but definitely498* good enough for a benchmarking framework.499*500* * Estimated capacity: @f$ 2^{51} @f$ bytes
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.