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