Merge #21170: bench: Add benchmark to write JSON into a string

e3e0a2432c Add benchmark to write JSON into a string (Martin Ankerl)

Pull request description:

  The benchmark `BlockToJsonVerbose` only tests generating (and destroying)
  the JSON data structure, but serializing into a string is also a
  performance critical aspect of the RPC calls.

  Extracts test setup into a `struct TestBlockAndIndex`, and uses it in
  both `BlockToJsonVerbose` and `BlockToJsonVerboseWrite`.

  Also, use `ankerl::nanobench::doNotOptimizeAway` to make sure the compiler
  can't optimize the result of the calls away.

  Here are benchmark results on my Intel i7-8700:

  |               ns/op |                op/s |    err% |          ins/op |          cyc/op |    IPC |         bra/op |   miss% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
  |       71,807,017.00 |               13.93 |    0.4% |  555,782,961.00 |  220,788,645.00 |  2.517 | 102,279,341.00 |    0.4% |      0.80 | `BlockToJsonVerbose`
  |       27,916,835.00 |               35.82 |    0.1% |  235,084,034.00 |   89,033,525.00 |  2.640 |  42,911,139.00 |    0.3% |      0.32 | `BlockToJsonVerboseWrite`

ACKs for top commit:
  laanwj:
    Code review ACK e3e0a2432c

Tree-SHA512: bc4d6d1588d47d4bd7af8e7908e44b8561bc391a2d73eccd7c0aa37fc40e8a9ce1fa1f3c29b416eef24a73c6bce3036839c0bbfe1b8dbd6d1bba3718b7ca5383
This commit is contained in:
Wladimir J. van der Laan 2021-03-01 19:07:46 +01:00
commit 05e821ee19
No known key found for this signature in database
GPG key ID: 1E4AED62986CD25D

View file

@ -12,25 +12,49 @@
#include <univalue.h>
namespace {
struct TestBlockAndIndex {
TestingSetup test_setup{};
CBlock block{};
uint256 blockHash{};
CBlockIndex blockindex{};
TestBlockAndIndex()
{
CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION);
char a = '\0';
stream.write(&a, 1); // Prevent compaction
stream >> block;
blockHash = block.GetHash();
blockindex.phashBlock = &blockHash;
blockindex.nBits = 403014710;
}
};
} // namespace
static void BlockToJsonVerbose(benchmark::Bench& bench)
{
TestingSetup test_setup{};
CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION);
char a = '\0';
stream.write(&a, 1); // Prevent compaction
CBlock block;
stream >> block;
CBlockIndex blockindex;
const uint256 blockHash = block.GetHash();
blockindex.phashBlock = &blockHash;
blockindex.nBits = 403014710;
TestBlockAndIndex data;
bench.run([&] {
(void)blockToJSON(block, &blockindex, &blockindex, /*verbose*/ true);
auto univalue = blockToJSON(data.block, &data.blockindex, &data.blockindex, /*verbose*/ true);
ankerl::nanobench::doNotOptimizeAway(univalue);
});
}
BENCHMARK(BlockToJsonVerbose);
static void BlockToJsonVerboseWrite(benchmark::Bench& bench)
{
TestBlockAndIndex data;
auto univalue = blockToJSON(data.block, &data.blockindex, &data.blockindex, /*verbose*/ true);
bench.run([&] {
auto str = univalue.write();
ankerl::nanobench::doNotOptimizeAway(str);
});
}
BENCHMARK(BlockToJsonVerboseWrite);