aboutsummaryrefslogtreecommitdiff
path: root/src/bench
diff options
context:
space:
mode:
Diffstat (limited to 'src/bench')
-rw-r--r--src/bench/bech32.cpp38
-rw-r--r--src/bench/bench.h12
-rw-r--r--src/bench/bench_bitcoin.cpp59
-rw-r--r--src/bench/block_assemble.cpp116
-rw-r--r--src/bench/coin_selection.cpp26
-rw-r--r--src/bench/crypto_hash.cpp9
-rw-r--r--src/bench/examples.cpp (renamed from src/bench/Examples.cpp)0
-rw-r--r--src/bench/merkle_root.cpp26
-rw-r--r--src/bench/prevector.cpp8
-rw-r--r--src/bench/verify_script.cpp1
10 files changed, 247 insertions, 48 deletions
diff --git a/src/bench/bech32.cpp b/src/bench/bech32.cpp
new file mode 100644
index 0000000000..ff655bded0
--- /dev/null
+++ b/src/bench/bech32.cpp
@@ -0,0 +1,38 @@
+// Copyright (c) 2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <bench/bench.h>
+
+#include <validation.h>
+#include <bech32.h>
+#include <utilstrencodings.h>
+
+#include <vector>
+#include <string>
+
+
+static void Bech32Encode(benchmark::State& state)
+{
+ std::vector<uint8_t> v = ParseHex("c97f5a67ec381b760aeaf67573bc164845ff39a3bb26a1cee401ac67243b48db");
+ std::vector<unsigned char> tmp = {0};
+ tmp.reserve(1 + 32 * 8 / 5);
+ ConvertBits<8, 5, true>([&](unsigned char c) { tmp.push_back(c); }, v.begin(), v.end());
+ while (state.KeepRunning()) {
+ bech32::Encode("bc", tmp);
+ }
+}
+
+
+static void Bech32Decode(benchmark::State& state)
+{
+ std::string addr = "bc1qkallence7tjawwvy0dwt4twc62qjgaw8f4vlhyd006d99f09";
+ std::vector<unsigned char> vch;
+ while (state.KeepRunning()) {
+ bech32::Decode(addr);
+ }
+}
+
+
+BENCHMARK(Bech32Encode, 800 * 1000);
+BENCHMARK(Bech32Decode, 800 * 1000);
diff --git a/src/bench/bench.h b/src/bench/bench.h
index e15cb81869..5d131c2aa8 100644
--- a/src/bench/bench.h
+++ b/src/bench/bench.h
@@ -111,9 +111,9 @@ public:
class ConsolePrinter : public Printer
{
public:
- void header();
- void result(const State& state);
- void footer();
+ void header() override;
+ void result(const State& state) override;
+ void footer() override;
};
// creates box plot with plotly.js
@@ -121,9 +121,9 @@ class PlotlyPrinter : public Printer
{
public:
PlotlyPrinter(std::string plotly_url, int64_t width, int64_t height);
- void header();
- void result(const State& state);
- void footer();
+ void header() override;
+ void result(const State& state) override;
+ void footer() override;
private:
std::string m_plotly_url;
diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp
index 1d87883522..f3302bfe5a 100644
--- a/src/bench/bench_bitcoin.cpp
+++ b/src/bench/bench_bitcoin.cpp
@@ -6,11 +6,10 @@
#include <crypto/sha256.h>
#include <key.h>
-#include <validation.h>
-#include <util.h>
#include <random.h>
-
-#include <boost/lexical_cast.hpp>
+#include <util.h>
+#include <utilstrencodings.h>
+#include <validation.h>
#include <memory>
@@ -22,39 +21,53 @@ static const char* DEFAULT_PLOT_PLOTLYURL = "https://cdn.plot.ly/plotly-latest.m
static const int64_t DEFAULT_PLOT_WIDTH = 1024;
static const int64_t DEFAULT_PLOT_HEIGHT = 768;
-int
-main(int argc, char** argv)
+static void SetupBenchArgs()
+{
+ gArgs.AddArg("-?", "Print this help message and exit", false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-list", "List benchmarks without executing them. Can be combined with -scaling and -filter", false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-evals=<n>", strprintf("Number of measurement evaluations to perform. (default: %u)", DEFAULT_BENCH_EVALUATIONS), false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-filter=<regex>", strprintf("Regular expression filter to select benchmark by name (default: %s)", DEFAULT_BENCH_FILTER), false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-scaling=<n>", strprintf("Scaling factor for benchmark's runtime (default: %u)", DEFAULT_BENCH_SCALING), false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-printer=(console|plot)", strprintf("Choose printer format. console: print data to console. plot: Print results as HTML graph (default: %s)", DEFAULT_BENCH_PRINTER), false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-plot-plotlyurl=<uri>", strprintf("URL to use for plotly.js (default: %s)", DEFAULT_PLOT_PLOTLYURL), false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-plot-width=<x>", strprintf("Plot width in pixel (default: %u)", DEFAULT_PLOT_WIDTH), false, OptionsCategory::OPTIONS);
+ gArgs.AddArg("-plot-height=<x>", strprintf("Plot height in pixel (default: %u)", DEFAULT_PLOT_HEIGHT), false, OptionsCategory::OPTIONS);
+
+ // Hidden
+ gArgs.AddArg("-h", "", false, OptionsCategory::HIDDEN);
+ gArgs.AddArg("-help", "", false, OptionsCategory::HIDDEN);
+}
+
+int main(int argc, char** argv)
{
- gArgs.ParseParameters(argc, argv);
+ SetupBenchArgs();
+ std::string error;
+ if (!gArgs.ParseParameters(argc, argv, error)) {
+ fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str());
+ return EXIT_FAILURE;
+ }
if (HelpRequested(gArgs)) {
- std::cout << HelpMessageGroup(_("Options:"))
- << HelpMessageOpt("-?", _("Print this help message and exit"))
- << HelpMessageOpt("-list", _("List benchmarks without executing them. Can be combined with -scaling and -filter"))
- << HelpMessageOpt("-evals=<n>", strprintf(_("Number of measurement evaluations to perform. (default: %u)"), DEFAULT_BENCH_EVALUATIONS))
- << HelpMessageOpt("-filter=<regex>", strprintf(_("Regular expression filter to select benchmark by name (default: %s)"), DEFAULT_BENCH_FILTER))
- << HelpMessageOpt("-scaling=<n>", strprintf(_("Scaling factor for benchmark's runtime (default: %u)"), DEFAULT_BENCH_SCALING))
- << HelpMessageOpt("-printer=(console|plot)", strprintf(_("Choose printer format. console: print data to console. plot: Print results as HTML graph (default: %s)"), DEFAULT_BENCH_PRINTER))
- << HelpMessageOpt("-plot-plotlyurl=<uri>", strprintf(_("URL to use for plotly.js (default: %s)"), DEFAULT_PLOT_PLOTLYURL))
- << HelpMessageOpt("-plot-width=<x>", strprintf(_("Plot width in pixel (default: %u)"), DEFAULT_PLOT_WIDTH))
- << HelpMessageOpt("-plot-height=<x>", strprintf(_("Plot height in pixel (default: %u)"), DEFAULT_PLOT_HEIGHT));
-
- return 0;
+ std::cout << gArgs.GetHelpMessage();
+
+ return EXIT_SUCCESS;
}
SHA256AutoDetect();
RandomInit();
ECC_Start();
SetupEnvironment();
- fPrintToDebugLog = false; // don't want to write to debug.log file
int64_t evaluations = gArgs.GetArg("-evals", DEFAULT_BENCH_EVALUATIONS);
std::string regex_filter = gArgs.GetArg("-filter", DEFAULT_BENCH_FILTER);
std::string scaling_str = gArgs.GetArg("-scaling", DEFAULT_BENCH_SCALING);
bool is_list_only = gArgs.GetBoolArg("-list", false);
- double scaling_factor = boost::lexical_cast<double>(scaling_str);
-
+ double scaling_factor;
+ if (!ParseDouble(scaling_str, &scaling_factor)) {
+ fprintf(stderr, "Error parsing scaling factor as double: %s\n", scaling_str.c_str());
+ return EXIT_FAILURE;
+ }
std::unique_ptr<benchmark::Printer> printer(new benchmark::ConsolePrinter());
std::string printer_arg = gArgs.GetArg("-printer", DEFAULT_BENCH_PRINTER);
@@ -68,4 +81,6 @@ main(int argc, char** argv)
benchmark::BenchRunner::RunAll(*printer, evaluations, scaling_factor, regex_filter, is_list_only);
ECC_Stop();
+
+ return EXIT_SUCCESS;
}
diff --git a/src/bench/block_assemble.cpp b/src/bench/block_assemble.cpp
new file mode 100644
index 0000000000..36fa175a76
--- /dev/null
+++ b/src/bench/block_assemble.cpp
@@ -0,0 +1,116 @@
+// Copyright (c) 2011-2017 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <bench/bench.h>
+#include <chainparams.h>
+#include <coins.h>
+#include <consensus/merkle.h>
+#include <consensus/validation.h>
+#include <miner.h>
+#include <policy/policy.h>
+#include <pow.h>
+#include <scheduler.h>
+#include <txdb.h>
+#include <txmempool.h>
+#include <utiltime.h>
+#include <validation.h>
+#include <validationinterface.h>
+
+#include <boost/thread.hpp>
+
+#include <list>
+#include <vector>
+
+static std::shared_ptr<CBlock> PrepareBlock(const CScript& coinbase_scriptPubKey)
+{
+ auto block = std::make_shared<CBlock>(
+ BlockAssembler{Params()}
+ .CreateNewBlock(coinbase_scriptPubKey, /* fMineWitnessTx */ true)
+ ->block);
+
+ block->nTime = ::chainActive.Tip()->GetMedianTimePast() + 1;
+ block->hashMerkleRoot = BlockMerkleRoot(*block);
+
+ return block;
+}
+
+
+static CTxIn MineBlock(const CScript& coinbase_scriptPubKey)
+{
+ auto block = PrepareBlock(coinbase_scriptPubKey);
+
+ while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
+ assert(++block->nNonce);
+ }
+
+ bool processed{ProcessNewBlock(Params(), block, true, nullptr)};
+ assert(processed);
+
+ return CTxIn{block->vtx[0]->GetHash(), 0};
+}
+
+
+static void AssembleBlock(benchmark::State& state)
+{
+ const std::vector<unsigned char> op_true{OP_TRUE};
+ CScriptWitness witness;
+ witness.stack.push_back(op_true);
+
+ uint256 witness_program;
+ CSHA256().Write(&op_true[0], op_true.size()).Finalize(witness_program.begin());
+
+ const CScript SCRIPT_PUB{CScript(OP_0) << std::vector<unsigned char>{witness_program.begin(), witness_program.end()}};
+
+ // Switch to regtest so we can mine faster
+ // Also segwit is active, so we can include witness transactions
+ SelectParams(CBaseChainParams::REGTEST);
+
+ InitScriptExecutionCache();
+
+ boost::thread_group thread_group;
+ CScheduler scheduler;
+ {
+ ::pblocktree.reset(new CBlockTreeDB(1 << 20, true));
+ ::pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true));
+ ::pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get()));
+
+ const CChainParams& chainparams = Params();
+ thread_group.create_thread(boost::bind(&CScheduler::serviceQueue, &scheduler));
+ GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
+ LoadGenesisBlock(chainparams);
+ CValidationState state;
+ ActivateBestChain(state, chainparams);
+ assert(::chainActive.Tip() != nullptr);
+ const bool witness_enabled{IsWitnessEnabled(::chainActive.Tip(), chainparams.GetConsensus())};
+ assert(witness_enabled);
+ }
+
+ // Collect some loose transactions that spend the coinbases of our mined blocks
+ constexpr size_t NUM_BLOCKS{200};
+ std::array<CTransactionRef, NUM_BLOCKS - COINBASE_MATURITY + 1> txs;
+ for (size_t b{0}; b < NUM_BLOCKS; ++b) {
+ CMutableTransaction tx;
+ tx.vin.push_back(MineBlock(SCRIPT_PUB));
+ tx.vin.back().scriptWitness = witness;
+ tx.vout.emplace_back(1337, SCRIPT_PUB);
+ if (NUM_BLOCKS - b >= COINBASE_MATURITY)
+ txs.at(b) = MakeTransactionRef(tx);
+ }
+ for (const auto& txr : txs) {
+ CValidationState state;
+ bool ret{::AcceptToMemoryPool(::mempool, state, txr, nullptr /* pfMissingInputs */, nullptr /* plTxnReplaced */, false /* bypass_limits */, /* nAbsurdFee */ 0)};
+ assert(ret);
+ }
+
+ while (state.KeepRunning()) {
+ PrepareBlock(SCRIPT_PUB);
+ }
+
+ thread_group.interrupt_all();
+ thread_group.join_all();
+ GetMainSignals().FlushBackgroundCallbacks();
+ GetMainSignals().UnregisterBackgroundSignalScheduler();
+}
+
+BENCHMARK(AssembleBlock, 700);
diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp
index 64ec056c4d..f3180809b5 100644
--- a/src/bench/coin_selection.cpp
+++ b/src/bench/coin_selection.cpp
@@ -34,31 +34,25 @@ static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector<CO
static void CoinSelection(benchmark::State& state)
{
const CWallet wallet("dummy", WalletDatabase::CreateDummy());
- std::vector<COutput> vCoins;
LOCK(wallet.cs_wallet);
- while (state.KeepRunning()) {
- // Add coins.
- for (int i = 0; i < 1000; i++)
- addCoin(1000 * COIN, wallet, vCoins);
- addCoin(3 * COIN, wallet, vCoins);
+ // Add coins.
+ std::vector<COutput> vCoins;
+ for (int i = 0; i < 1000; ++i) {
+ addCoin(1000 * COIN, wallet, vCoins);
+ }
+ addCoin(3 * COIN, wallet, vCoins);
+ const CoinEligibilityFilter filter_standard(1, 6, 0);
+ const CoinSelectionParams coin_selection_params(true, 34, 148, CFeeRate(0), 0);
+ while (state.KeepRunning()) {
std::set<CInputCoin> setCoinsRet;
CAmount nValueRet;
bool bnb_used;
- CoinEligibilityFilter filter_standard(1, 6, 0);
- CoinSelectionParams coin_selection_params(false, 34, 148, CFeeRate(0), 0);
- bool success = wallet.SelectCoinsMinConf(1003 * COIN, filter_standard, vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)
- || wallet.SelectCoinsMinConf(1003 * COIN, filter_standard, vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used);
+ bool success = wallet.SelectCoinsMinConf(1003 * COIN, filter_standard, vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used);
assert(success);
assert(nValueRet == 1003 * COIN);
assert(setCoinsRet.size() == 2);
-
- // Empty wallet.
- for (COutput& output : vCoins) {
- delete output.tx;
- }
- vCoins.clear();
}
}
diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp
index adb69bc6c3..7d907eaf10 100644
--- a/src/bench/crypto_hash.cpp
+++ b/src/bench/crypto_hash.cpp
@@ -52,6 +52,14 @@ static void SHA256_32b(benchmark::State& state)
}
}
+static void SHA256D64_1024(benchmark::State& state)
+{
+ std::vector<uint8_t> in(64 * 1024, 0);
+ while (state.KeepRunning()) {
+ SHA256D64(in.data(), in.data(), 1024);
+ }
+}
+
static void SHA512(benchmark::State& state)
{
uint8_t hash[CSHA512::OUTPUT_SIZE];
@@ -94,5 +102,6 @@ BENCHMARK(SHA512, 330);
BENCHMARK(SHA256_32b, 4700 * 1000);
BENCHMARK(SipHash_32b, 40 * 1000 * 1000);
+BENCHMARK(SHA256D64_1024, 7400);
BENCHMARK(FastRandom_32bit, 110 * 1000 * 1000);
BENCHMARK(FastRandom_1bit, 440 * 1000 * 1000);
diff --git a/src/bench/Examples.cpp b/src/bench/examples.cpp
index b68c9cd156..b68c9cd156 100644
--- a/src/bench/Examples.cpp
+++ b/src/bench/examples.cpp
diff --git a/src/bench/merkle_root.cpp b/src/bench/merkle_root.cpp
new file mode 100644
index 0000000000..fab12da311
--- /dev/null
+++ b/src/bench/merkle_root.cpp
@@ -0,0 +1,26 @@
+// Copyright (c) 2016 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <bench/bench.h>
+
+#include <uint256.h>
+#include <random.h>
+#include <consensus/merkle.h>
+
+static void MerkleRoot(benchmark::State& state)
+{
+ FastRandomContext rng(true);
+ std::vector<uint256> leaves;
+ leaves.resize(9001);
+ for (auto& item : leaves) {
+ item = rng.rand256();
+ }
+ while (state.KeepRunning()) {
+ bool mutation = false;
+ uint256 hash = ComputeMerkleRoot(std::vector<uint256>(leaves), &mutation);
+ leaves[mutation] = hash;
+ }
+}
+
+BENCHMARK(MerkleRoot, 800);
diff --git a/src/bench/prevector.cpp b/src/bench/prevector.cpp
index d0f28d1a3e..09c7020848 100644
--- a/src/bench/prevector.cpp
+++ b/src/bench/prevector.cpp
@@ -42,13 +42,13 @@ static void PrevectorClear(benchmark::State& state)
t0.resize(28);
t0.clear();
t1.resize(29);
- t0.clear();
+ t1.clear();
}
}
}
template <typename T>
-void PrevectorResize(benchmark::State& state)
+static void PrevectorResize(benchmark::State& state)
{
while (state.KeepRunning()) {
prevector<28, T> t0;
@@ -64,11 +64,11 @@ void PrevectorResize(benchmark::State& state)
#define PREVECTOR_TEST(name, nontrivops, trivops) \
static void Prevector ## name ## Nontrivial(benchmark::State& state) { \
- PrevectorResize<nontrivial_t>(state); \
+ Prevector ## name<nontrivial_t>(state); \
} \
BENCHMARK(Prevector ## name ## Nontrivial, nontrivops); \
static void Prevector ## name ## Trivial(benchmark::State& state) { \
- PrevectorResize<trivial_t>(state); \
+ Prevector ## name<trivial_t>(state); \
} \
BENCHMARK(Prevector ## name ## Trivial, trivops);
diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp
index 4100519d48..ae60588c2d 100644
--- a/src/bench/verify_script.cpp
+++ b/src/bench/verify_script.cpp
@@ -9,6 +9,7 @@
#endif
#include <script/script.h>
#include <script/sign.h>
+#include <script/standard.h>
#include <streams.h>
#include <array>