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.
1251explicit SetupRunner(SetupOp setupOp, Bench& bench)1252: mSetupOp(std::move(setupOp))1253, mBench(bench) {}1255template <typename Op>1256ANKERL_NANOBENCH_NO_SANITIZE("integer")1257Bench& run(Op&& op) {1258assert((mBench.epochIterations() <= 1) &&1259"setup() runs once per epoch, not once per iteration; it requires epochIterations(1)");1260mBench.epochIterations(1);1261return mBench.runImpl(mSetupOp, std::forward<Op>(op));1262}1264private:1265SetupOp mSetupOp;1266Bench& mBench;1267};1268} // namespace detail1270template <typename Op>1271ANKERL_NANOBENCH_NO_SANITIZE("integer")1272Bench& Bench::run(Op&& op) {1273auto setupOp = [] {};1274return runImpl(setupOp, std::forward<Op>(op));1275}1277template <typename SetupOp, typename Op>1278ANKERL_NANOBENCH_NO_SANITIZE("integer")1279Bench& Bench::runImpl(SetupOp& setupOp, Op&& op) {1280// It is important that this method is kept short so the compiler can do better optimizations/ inlining of op()1281detail::IterationLogic iterationLogic(*this);1282auto& pc = detail::performanceCounters();1284while (auto n = iterationLogic.numIters()) {1285setupOp();1287pc.beginMeasure();1288Clock::time_point const before = Clock::now();1289while (n-- > 0) {1290op();1291}1292Clock::time_point const after = Clock::now();1293pc.endMeasure();1294pc.updateResults(iterationLogic.numIters());1295iterationLogic.add(after - before, pc);1296}1297iterationLogic.moveResultTo(mResults);1298return *this;1299}1301template <typename SetupOp>1302detail::SetupRunner<SetupOp> Bench::setup(SetupOp setupOp) {1303return detail::SetupRunner<SetupOp>(std::move(setupOp), *this);1304}1306// Performs all evaluations.1307template <typename Op>1308Bench& Bench::run(char const* benchmarkName, Op&& op) {1309name(benchmarkName);1310return run(std::forward<Op>(op));1311}1313template <typename Op>1314Bench& Bench::run(std::string const& benchmarkName, Op&& op) {1315name(benchmarkName);1316return run(std::forward<Op>(op));1317}1319template <typename Op>1320BigO Bench::complexityBigO(char const* benchmarkName, Op op) const {1321return BigO(benchmarkName, BigO::collectRangeMeasure(mResults), op);1322}1324template <typename Op>1325BigO Bench::complexityBigO(std::string const& benchmarkName, Op op) const {1326return BigO(benchmarkName, BigO::collectRangeMeasure(mResults), op);1327}1329// Set the batch size, e.g. number of processed bytes, or some other metric for the size of the processed data in each iteration.1330// Any argument is cast to double.1331template <typename T>1332Bench& Bench::batch(T b) noexcept {1333mConfig.mBatch = static_cast<double>(b);1334return *this;1335}1337// Sets the computation complexity of the next run. Any argument is cast to double.1338template <typename T>1339Bench& Bench::complexityN(T n) noexcept {1340mConfig.mComplexityN = static_cast<double>(n);1341return *this;1342}1344// Convenience: makes sure none of the given arguments are optimized away by the compiler.1345template <typename Arg>1346Bench& Bench::doNotOptimizeAway(Arg&& arg) {1347detail::doNotOptimizeAway(std::forward<Arg>(arg));1348return *this;1349}1351// Makes sure none of the given arguments are optimized away by the compiler.1352template <typename Arg>1353void doNotOptimizeAway(Arg&& arg) {1354detail::doNotOptimizeAway(std::forward<Arg>(arg));1355}1357namespace detail {1359#if defined(_MSC_VER)1360template <typename T>1361void doNotOptimizeAway(T const& val) {1362doNotOptimizeAwaySink(&val);1363}1365#endif1367} // namespace detail1368} // namespace nanobench1369} // namespace ankerl1371#if defined(ANKERL_NANOBENCH_IMPLEMENT)1372// NOLINTBEGIN(misc-definitions-in-headers)1374///////////////////////////////////////////////////////////////////////////////////////////////////1375// implementation part - only visible in .cpp1376///////////////////////////////////////////////////////////////////////////////////////////////////1378# include <algorithm> // sort, reverse1379# include <cmath>1380# include <compare>1381# include <cstdlib> // getenv1382# include <fstream> // ifstream to parse proc files1383# include <functional>1384# include <iomanip> // setw, setprecision1385# include <iostream> // cout1386# include <iterator>1387# include <locale>1388# include <numeric> // accumulate1389# include <random> // random_device1390# include <sstream> // to_s in Number1391# include <stdexcept> // throw for rendering templates1392# include <tuple> // std::tie1393# if defined(__linux__)1394# include <unistd.h> //sysconf1395# endif1396# if ANKERL_NANOBENCH(PERF_COUNTERS)1397# include <map> // map1399# include <linux/perf_event.h>1400# include <sys/ioctl.h>1401# include <sys/syscall.h>1402# include <sys/types.h>1403# endif1405// declarations ///////////////////////////////////////////////////////////////////////////////////1407// As definitions follow these declarations within this1408// header, IWYU considers some of them redundant and1409// suggests removing them. Disable this IWYU behavior.1410// IWYU pragma: begin_keep1412namespace ankerl {1413namespace nanobench {1415// helper stuff that is only intended to be used internally1416namespace detail {1418// formatting utilities1419namespace fmt {1421class NumSep;1422class StreamStateRestorer;1423class Number;1424class MarkDownColumn;1425class MarkDownCode;1427} // namespace fmt1428} // namespace detail1429} // namespace nanobench1430} // namespace ankerl1432// IWYU pragma: end_keep1434// definitions ////////////////////////////////////////////////////////////////////////////////////1436namespace ankerl {1437namespace nanobench {1439uint64_t splitMix64(uint64_t& state) noexcept;1441namespace detail {1443// helpers to get double values1444template <typename T>1445inline double d(T t) noexcept {1446return static_cast<double>(t);1447}1448inline double d(Clock::duration duration) noexcept {1449return std::chrono::duration_cast<std::chrono::duration<double>>(duration).count();1450}1452// Calculates clock resolution once, and remembers the result1453inline Clock::duration clockResolution() noexcept;1455} // namespace detail1457namespace templates {1459char const* csv() noexcept {1460return R"DELIM("title";"name";"unit";"batch";"elapsed";"error %";"instructions";"branches";"branch misses";"total"1461{{#result}}"{{title}}";"{{name}}";"{{unit}}";{{batch}};{{median(elapsed)}};{{medianAbsolutePercentError(elapsed)}};{{median(instructions)}};{{median(branchinstructions)}};{{median(branchmisses)}};{{sumProduct(iterations, elapsed)}}1462{{/result}})DELIM";1463}1465char const* htmlBoxplot() noexcept {1466return R"DELIM(<html>1468<head>1469<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>1470</head>1472<body>1473<div id="myDiv"></div>1474<script>1475var data = [1476{{#result}}{1477name: '{{name}}',1478y: [{{#measurement}}{{elapsed}}{{^-last}}, {{/last}}{{/measurement}}],1479},1480{{/result}}1481];1482var title = '{{title}}';1484data = data.map(a => Object.assign(a, { boxpoints: 'all', pointpos: 0, type: 'box' }));1485var layout = { title: { text: title }, showlegend: false, yaxis: { title: 'time per unit', rangemode: 'tozero', autorange: true } }; Plotly.newPlot('myDiv', data, layout, {responsive: true});1486</script>1487</body>1489</html>)DELIM";1490}1492char const* pyperf() noexcept {1493return R"DELIM({1494"benchmarks": [1495{1496"runs": [1497{1498"values": [1499{{#measurement}} {{elapsed}}{{^-last}},1500{{/last}}{{/measurement}}
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.