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