bench: measure block (size)serialization speed

The SizeComputer is a special serializer which returns what the exact final size will be of the serialized content.

> cmake -B build -DBUILD_BENCH=ON -DCMAKE_BUILD_TYPE=Release && cmake --build build -j$(nproc) && build/bin/bench_bitcoin -filter='SizeComputerBlock|SerializeBlock' --min-time=10000

> C compiler ............................ AppleClang 16.0.0.16000026

|            ns/block |             block/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|          195,610.62 |            5,112.20 |    0.3% |     11.00 | `SerializeBlock`
|           12,061.83 |           82,906.19 |    0.1% |     11.01 | `SizeComputerBlock`

> C++ compiler .......................... GNU 13.3.0

|            ns/block |             block/s |    err% |       ins/block |       cyc/block |    IPC |      bra/block |   miss% |     total | benchmark
|--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
|          867,857.55 |            1,152.26 |    0.0% |    8,015,883.90 |    3,116,099.08 |  2.572 |   1,517,035.87 |    0.5% |     10.81 | `SerializeBlock`
|           30,928.27 |           32,332.88 |    0.0% |      221,683.03 |      111,055.84 |  1.996 |      53,037.03 |    0.8% |     11.03 | `SizeComputerBlock`
This commit is contained in:
Lőrinc 2024-11-19 16:11:56 +01:00
parent 73cfebb08b
commit 3d7c8ae9fb
2 changed files with 30 additions and 4 deletions

View file

@ -21,11 +21,34 @@
#include <optional>
#include <vector>
static void SizeComputerBlock(benchmark::Bench& bench) {
CBlock block;
DataStream(benchmark::data::block413567) >> TX_WITH_WITNESS(block);
bench.unit("block").run([&] {
SizeComputer size_computer;
size_computer << TX_WITH_WITNESS(block);
assert(size_computer.size() == benchmark::data::block413567.size());
});
}
static void SerializeBlock(benchmark::Bench& bench) {
CBlock block;
DataStream(benchmark::data::block413567) >> TX_WITH_WITNESS(block);
// Create output stream and verify first serialization matches input
bench.unit("block").run([&] {
DataStream output_stream(benchmark::data::block413567.size());
output_stream << TX_WITH_WITNESS(block);
assert(output_stream.size() == benchmark::data::block413567.size());
});
}
// These are the two major time-sinks which happen after we have fully received
// a block off the wire, but before we can relay the block on to peers using
// compact block relay.
static void DeserializeBlockTest(benchmark::Bench& bench)
static void DeserializeBlock(benchmark::Bench& bench)
{
DataStream stream(benchmark::data::block413567);
std::byte a{0};
@ -39,7 +62,7 @@ static void DeserializeBlockTest(benchmark::Bench& bench)
});
}
static void DeserializeAndCheckBlockTest(benchmark::Bench& bench)
static void DeserializeAndCheckBlock(benchmark::Bench& bench)
{
DataStream stream(benchmark::data::block413567);
std::byte a{0};
@ -60,5 +83,7 @@ static void DeserializeAndCheckBlockTest(benchmark::Bench& bench)
});
}
BENCHMARK(DeserializeBlockTest, benchmark::PriorityLevel::HIGH);
BENCHMARK(DeserializeAndCheckBlockTest, benchmark::PriorityLevel::HIGH);
BENCHMARK(SizeComputerBlock, benchmark::PriorityLevel::HIGH);
BENCHMARK(SerializeBlock, benchmark::PriorityLevel::HIGH);
BENCHMARK(DeserializeBlock, benchmark::PriorityLevel::HIGH);
BENCHMARK(DeserializeAndCheckBlock, benchmark::PriorityLevel::HIGH);

View file

@ -141,6 +141,7 @@ public:
typedef vector_type::reverse_iterator reverse_iterator;
explicit DataStream() = default;
explicit DataStream(size_type n) { reserve(n); }
explicit DataStream(std::span<const uint8_t> sp) : DataStream{std::as_bytes(sp)} {}
explicit DataStream(std::span<const value_type> sp) : vch(sp.data(), sp.data() + sp.size()) {}