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