diff --git a/src/bench/rpc_blockchain.cpp b/src/bench/rpc_blockchain.cpp index df951a14e49..52916242fa5 100644 --- a/src/bench/rpc_blockchain.cpp +++ b/src/bench/rpc_blockchain.cpp @@ -45,17 +45,34 @@ struct TestBlockAndIndex { } // namespace -static void BlockToJsonVerbose(benchmark::Bench& bench) +static void BlockToJson(benchmark::Bench& bench, TxVerbosity verbosity) { TestBlockAndIndex data; const uint256 pow_limit{data.testing_setup->m_node.chainman->GetParams().GetConsensus().powLimit}; bench.run([&] { - auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT, pow_limit); + auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, verbosity, pow_limit); ankerl::nanobench::doNotOptimizeAway(univalue); }); } -BENCHMARK(BlockToJsonVerbose, benchmark::PriorityLevel::HIGH); +static void BlockToJsonVerbosity1(benchmark::Bench& bench) +{ + BlockToJson(bench, TxVerbosity::SHOW_TXID); +} + +static void BlockToJsonVerbosity2(benchmark::Bench& bench) +{ + BlockToJson(bench, TxVerbosity::SHOW_DETAILS); +} + +static void BlockToJsonVerbosity3(benchmark::Bench& bench) +{ + BlockToJson(bench, TxVerbosity::SHOW_DETAILS_AND_PREVOUT); +} + +BENCHMARK(BlockToJsonVerbosity1, benchmark::PriorityLevel::HIGH); +BENCHMARK(BlockToJsonVerbosity2, benchmark::PriorityLevel::HIGH); +BENCHMARK(BlockToJsonVerbosity3, benchmark::PriorityLevel::HIGH); static void BlockToJsonVerboseWrite(benchmark::Bench& bench) { diff --git a/src/core_write.cpp b/src/core_write.cpp index 253dfde1006..14836f51489 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -181,6 +181,7 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry entry.pushKV("locktime", (int64_t)tx.nLockTime); UniValue vin{UniValue::VARR}; + vin.reserve(tx.vin.size()); // If available, use Undo data to calculate the fee. Note that txundo == nullptr // for coinbase transactions and for transactions where undo data is unavailable. @@ -203,6 +204,7 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry } if (!tx.vin[i].scriptWitness.IsNull()) { UniValue txinwitness(UniValue::VARR); + txinwitness.reserve(tx.vin[i].scriptWitness.stack.size()); for (const auto& item : tx.vin[i].scriptWitness.stack) { txinwitness.push_back(HexStr(item)); } @@ -232,6 +234,7 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry entry.pushKV("vin", std::move(vin)); UniValue vout(UniValue::VARR); + vout.reserve(tx.vout.size()); for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index ac1ce6285f7..0ac36b005ec 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -184,6 +184,7 @@ UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIn result.pushKV("size", (int)::GetSerializeSize(TX_WITH_WITNESS(block))); result.pushKV("weight", (int)::GetBlockWeight(block)); UniValue txs(UniValue::VARR); + txs.reserve(block.vtx.size()); switch (verbosity) { case TxVerbosity::SHOW_TXID: diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index 19a500d191a..bc71677bab6 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -70,6 +70,8 @@ public: size_t size() const { return values.size(); } + void reserve(size_t new_cap); + void getObjMap(std::map& kv) const; bool checkObject(const std::map& memberTypes) const; const UniValue& operator[](const std::string& key) const; diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index 656d2e82030..4d37c81fe87 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -240,3 +240,10 @@ const UniValue& UniValue::find_value(std::string_view key) const return NullUniValue; } +void UniValue::reserve(size_t new_cap) +{ + values.reserve(new_cap); + if (typ == VOBJ) { + keys.reserve(new_cap); + } +}