git / moonbite-core / src/bench/addrman.cpp · raw
// Copyright (c) 2020-2020 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 <addrman.h>#include <bench/bench.h>#include <random.h>#include <util/time.h>#include <vector>/* A "source" is a source address from which we have received a bunch of other addresses. */static constexpr size_t NUM_SOURCES = 64;static constexpr size_t NUM_ADDRESSES_PER_SOURCE = 256;static std::vector<CAddress> g_sources;static std::vector<std::vector<CAddress>> g_addresses;static void CreateAddresses(){ if (g_sources.size() > 0) { // already created return; } FastRandomContext rng(uint256(std::vector<unsigned char>(32, 123))); auto randAddr = [&rng]() { in6_addr addr; memcpy(&addr, rng.randbytes(sizeof(addr)).data(), sizeof(addr)); uint16_t port; memcpy(&port, rng.randbytes(sizeof(port)).data(), sizeof(port)); if (port == 0) { port = 1; } CAddress ret(CService(addr, port), NODE_NETWORK); ret.nTime = GetAdjustedTime(); return ret; }; for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) { g_sources.emplace_back(randAddr()); g_addresses.emplace_back(); for (size_t addr_i = 0; addr_i < NUM_ADDRESSES_PER_SOURCE; ++addr_i) { g_addresses[source_i].emplace_back(randAddr()); } }}static void AddAddressesToAddrMan(CAddrMan& addrman){ for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) { addrman.Add(g_addresses[source_i], g_sources[source_i]); }}static void FillAddrMan(CAddrMan& addrman){ CreateAddresses(); AddAddressesToAddrMan(addrman);}/* Benchmarks */static void AddrManAdd(benchmark::Bench& bench){ CreateAddresses(); CAddrMan addrman; bench.run([&] { AddAddressesToAddrMan(addrman); addrman.Clear(); });}static void AddrManSelect(benchmark::Bench& bench){ CAddrMan addrman; FillAddrMan(addrman); bench.run([&] { const auto& address = addrman.Select(); assert(address.GetPort() > 0); });}static void AddrManGetAddr(benchmark::Bench& bench){ CAddrMan addrman; FillAddrMan(addrman); bench.run([&] { const auto& addresses = addrman.GetAddr(2500, 23); assert(addresses.size() > 0); });}static void AddrManGood(benchmark::Bench& bench){ /* Create many CAddrMan objects - one to be modified at each loop iteration. * This is necessary because the CAddrMan::Good() method modifies the * object, affecting the timing of subsequent calls to the same method and * we want to do the same amount of work in every loop iteration. */ bench.epochs(5).epochIterations(1); std::vector<CAddrMan> addrmans(bench.epochs() * bench.epochIterations()); for (auto& addrman : addrmans) { FillAddrMan(addrman); } auto markSomeAsGood = [](CAddrMan& addrman) { for (size_t source_i = 0; source_i < NUM_SOURCES; ++source_i) { for (size_t addr_i = 0; addr_i < NUM_ADDRESSES_PER_SOURCE; ++addr_i) { if (addr_i % 32 == 0) { addrman.Good(g_addresses[source_i][addr_i]); } } } }; uint64_t i = 0; bench.run([&] { markSomeAsGood(addrmans.at(i)); ++i; });}BENCHMARK(AddrManAdd);BENCHMARK(AddrManSelect);BENCHMARK(AddrManGetAddr);BENCHMARK(AddrManGood);