prevector.cpp
1 // Copyright (c) 2015-2022 The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #include <prevector.h> 6 7 #include <bench/bench.h> 8 #include <serialize.h> 9 #include <streams.h> 10 11 #include <type_traits> 12 #include <vector> 13 14 struct nontrivial_t { 15 int x{-1}; 16 nontrivial_t() = default; 17 SERIALIZE_METHODS(nontrivial_t, obj) { READWRITE(obj.x); } 18 }; 19 static_assert(!std::is_trivially_default_constructible_v<nontrivial_t>, 20 "expected nontrivial_t to not be trivially constructible"); 21 22 typedef unsigned char trivial_t; 23 static_assert(std::is_trivially_default_constructible_v<trivial_t>, 24 "expected trivial_t to be trivially constructible"); 25 26 template <typename T> 27 static void PrevectorDestructor(benchmark::Bench& bench) 28 { 29 bench.batch(2).run([&] { 30 prevector<28, T> t0; 31 prevector<28, T> t1; 32 t0.resize(28); 33 t1.resize(29); 34 }); 35 } 36 37 template <typename T> 38 static void PrevectorClear(benchmark::Bench& bench) 39 { 40 prevector<28, T> t0; 41 prevector<28, T> t1; 42 bench.batch(2).run([&] { 43 t0.resize(28); 44 t0.clear(); 45 t1.resize(29); 46 t1.clear(); 47 }); 48 } 49 50 template <typename T> 51 static void PrevectorResize(benchmark::Bench& bench) 52 { 53 prevector<28, T> t0; 54 prevector<28, T> t1; 55 bench.batch(4).run([&] { 56 t0.resize(28); 57 t0.resize(0); 58 t1.resize(29); 59 t1.resize(0); 60 }); 61 } 62 63 template <typename T> 64 static void PrevectorDeserialize(benchmark::Bench& bench) 65 { 66 DataStream s0{}; 67 prevector<28, T> t0; 68 t0.resize(28); 69 for (auto x = 0; x < 900; ++x) { 70 s0 << t0; 71 } 72 t0.resize(100); 73 for (auto x = 0; x < 101; ++x) { 74 s0 << t0; 75 } 76 bench.batch(1000).run([&] { 77 prevector<28, T> t1; 78 for (auto x = 0; x < 1000; ++x) { 79 s0 >> t1; 80 } 81 s0.Rewind(); 82 }); 83 } 84 85 template <typename T> 86 static void PrevectorFillVectorDirect(benchmark::Bench& bench) 87 { 88 bench.run([&] { 89 std::vector<prevector<28, T>> vec; 90 vec.reserve(260); 91 for (size_t i = 0; i < 260; ++i) { 92 vec.emplace_back(); 93 } 94 }); 95 } 96 97 98 template <typename T> 99 static void PrevectorFillVectorIndirect(benchmark::Bench& bench) 100 { 101 bench.run([&] { 102 std::vector<prevector<28, T>> vec; 103 vec.reserve(260); 104 for (size_t i = 0; i < 260; ++i) { 105 // force allocation 106 vec.emplace_back(29, T{}); 107 } 108 }); 109 } 110 111 #define PREVECTOR_TEST(name) \ 112 static void Prevector##name##Nontrivial(benchmark::Bench& bench) \ 113 { \ 114 Prevector##name<nontrivial_t>(bench); \ 115 } \ 116 BENCHMARK(Prevector##name##Nontrivial, benchmark::PriorityLevel::HIGH); \ 117 static void Prevector##name##Trivial(benchmark::Bench& bench) \ 118 { \ 119 Prevector##name<trivial_t>(bench); \ 120 } \ 121 BENCHMARK(Prevector##name##Trivial, benchmark::PriorityLevel::HIGH); 122 123 PREVECTOR_TEST(Clear) 124 PREVECTOR_TEST(Destructor) 125 PREVECTOR_TEST(Resize) 126 PREVECTOR_TEST(Deserialize) 127 PREVECTOR_TEST(FillVectorDirect) 128 PREVECTOR_TEST(FillVectorIndirect)