xref: /aosp_15_r20/external/libcxx/benchmarks/ordered_set.bench.cpp (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
1*58b9f456SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2*58b9f456SAndroid Build Coastguard Worker //
3*58b9f456SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*58b9f456SAndroid Build Coastguard Worker //
5*58b9f456SAndroid Build Coastguard Worker // This file is dual licensed under the MIT and the University of Illinois Open
6*58b9f456SAndroid Build Coastguard Worker // Source Licenses. See LICENSE.TXT for details.
7*58b9f456SAndroid Build Coastguard Worker //
8*58b9f456SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*58b9f456SAndroid Build Coastguard Worker 
10*58b9f456SAndroid Build Coastguard Worker #include <algorithm>
11*58b9f456SAndroid Build Coastguard Worker #include <cstdint>
12*58b9f456SAndroid Build Coastguard Worker #include <memory>
13*58b9f456SAndroid Build Coastguard Worker #include <random>
14*58b9f456SAndroid Build Coastguard Worker #include <set>
15*58b9f456SAndroid Build Coastguard Worker #include <string>
16*58b9f456SAndroid Build Coastguard Worker #include <vector>
17*58b9f456SAndroid Build Coastguard Worker 
18*58b9f456SAndroid Build Coastguard Worker #include "CartesianBenchmarks.hpp"
19*58b9f456SAndroid Build Coastguard Worker #include "benchmark/benchmark.h"
20*58b9f456SAndroid Build Coastguard Worker #include "test_macros.h"
21*58b9f456SAndroid Build Coastguard Worker 
22*58b9f456SAndroid Build Coastguard Worker namespace {
23*58b9f456SAndroid Build Coastguard Worker 
24*58b9f456SAndroid Build Coastguard Worker enum class HitType { Hit, Miss };
25*58b9f456SAndroid Build Coastguard Worker 
26*58b9f456SAndroid Build Coastguard Worker struct AllHitTypes : EnumValuesAsTuple<AllHitTypes, HitType, 2> {
27*58b9f456SAndroid Build Coastguard Worker   static constexpr const char* Names[] = {"Hit", "Miss"};
28*58b9f456SAndroid Build Coastguard Worker };
29*58b9f456SAndroid Build Coastguard Worker 
30*58b9f456SAndroid Build Coastguard Worker enum class AccessPattern { Ordered, Random };
31*58b9f456SAndroid Build Coastguard Worker 
32*58b9f456SAndroid Build Coastguard Worker struct AllAccessPattern
33*58b9f456SAndroid Build Coastguard Worker     : EnumValuesAsTuple<AllAccessPattern, AccessPattern, 2> {
34*58b9f456SAndroid Build Coastguard Worker   static constexpr const char* Names[] = {"Ordered", "Random"};
35*58b9f456SAndroid Build Coastguard Worker };
36*58b9f456SAndroid Build Coastguard Worker 
sortKeysBy(std::vector<uint64_t> & Keys,AccessPattern AP)37*58b9f456SAndroid Build Coastguard Worker void sortKeysBy(std::vector<uint64_t>& Keys, AccessPattern AP) {
38*58b9f456SAndroid Build Coastguard Worker   if (AP == AccessPattern::Random) {
39*58b9f456SAndroid Build Coastguard Worker     std::random_device R;
40*58b9f456SAndroid Build Coastguard Worker     std::mt19937 M(R());
41*58b9f456SAndroid Build Coastguard Worker     std::shuffle(std::begin(Keys), std::end(Keys), M);
42*58b9f456SAndroid Build Coastguard Worker   }
43*58b9f456SAndroid Build Coastguard Worker }
44*58b9f456SAndroid Build Coastguard Worker 
45*58b9f456SAndroid Build Coastguard Worker struct TestSets {
46*58b9f456SAndroid Build Coastguard Worker   std::vector<std::set<uint64_t> > Sets;
47*58b9f456SAndroid Build Coastguard Worker   std::vector<uint64_t> Keys;
48*58b9f456SAndroid Build Coastguard Worker };
49*58b9f456SAndroid Build Coastguard Worker 
makeTestingSets(size_t TableSize,size_t NumTables,HitType Hit,AccessPattern Access)50*58b9f456SAndroid Build Coastguard Worker TestSets makeTestingSets(size_t TableSize, size_t NumTables, HitType Hit,
51*58b9f456SAndroid Build Coastguard Worker                          AccessPattern Access) {
52*58b9f456SAndroid Build Coastguard Worker   TestSets R;
53*58b9f456SAndroid Build Coastguard Worker   R.Sets.resize(1);
54*58b9f456SAndroid Build Coastguard Worker 
55*58b9f456SAndroid Build Coastguard Worker   for (uint64_t I = 0; I < TableSize; ++I) {
56*58b9f456SAndroid Build Coastguard Worker     R.Sets[0].insert(2 * I);
57*58b9f456SAndroid Build Coastguard Worker     R.Keys.push_back(Hit == HitType::Hit ? 2 * I : 2 * I + 1);
58*58b9f456SAndroid Build Coastguard Worker   }
59*58b9f456SAndroid Build Coastguard Worker   R.Sets.resize(NumTables, R.Sets[0]);
60*58b9f456SAndroid Build Coastguard Worker   sortKeysBy(R.Keys, Access);
61*58b9f456SAndroid Build Coastguard Worker 
62*58b9f456SAndroid Build Coastguard Worker   return R;
63*58b9f456SAndroid Build Coastguard Worker }
64*58b9f456SAndroid Build Coastguard Worker 
65*58b9f456SAndroid Build Coastguard Worker struct Base {
66*58b9f456SAndroid Build Coastguard Worker   size_t TableSize;
67*58b9f456SAndroid Build Coastguard Worker   size_t NumTables;
Base__anonfb3b86bc0111::Base68*58b9f456SAndroid Build Coastguard Worker   Base(size_t T, size_t N) : TableSize(T), NumTables(N) {}
69*58b9f456SAndroid Build Coastguard Worker 
skip__anonfb3b86bc0111::Base70*58b9f456SAndroid Build Coastguard Worker   bool skip() const {
71*58b9f456SAndroid Build Coastguard Worker     size_t Total = TableSize * NumTables;
72*58b9f456SAndroid Build Coastguard Worker     return Total < 100 || Total > 1000000;
73*58b9f456SAndroid Build Coastguard Worker   }
74*58b9f456SAndroid Build Coastguard Worker 
baseName__anonfb3b86bc0111::Base75*58b9f456SAndroid Build Coastguard Worker   std::string baseName() const {
76*58b9f456SAndroid Build Coastguard Worker     return "_TableSize" + std::to_string(TableSize) + "_NumTables" +
77*58b9f456SAndroid Build Coastguard Worker            std::to_string(NumTables);
78*58b9f456SAndroid Build Coastguard Worker   }
79*58b9f456SAndroid Build Coastguard Worker };
80*58b9f456SAndroid Build Coastguard Worker 
81*58b9f456SAndroid Build Coastguard Worker template <class Access>
82*58b9f456SAndroid Build Coastguard Worker struct Create : Base {
83*58b9f456SAndroid Build Coastguard Worker   using Base::Base;
84*58b9f456SAndroid Build Coastguard Worker 
run__anonfb3b86bc0111::Create85*58b9f456SAndroid Build Coastguard Worker   void run(benchmark::State& State) const {
86*58b9f456SAndroid Build Coastguard Worker     std::vector<uint64_t> Keys(TableSize);
87*58b9f456SAndroid Build Coastguard Worker     std::iota(Keys.begin(), Keys.end(), uint64_t{0});
88*58b9f456SAndroid Build Coastguard Worker     sortKeysBy(Keys, Access());
89*58b9f456SAndroid Build Coastguard Worker 
90*58b9f456SAndroid Build Coastguard Worker     while (State.KeepRunningBatch(TableSize * NumTables)) {
91*58b9f456SAndroid Build Coastguard Worker       std::vector<std::set<uint64_t>> Sets(NumTables);
92*58b9f456SAndroid Build Coastguard Worker       for (auto K : Keys) {
93*58b9f456SAndroid Build Coastguard Worker         for (auto& Set : Sets) {
94*58b9f456SAndroid Build Coastguard Worker           benchmark::DoNotOptimize(Set.insert(K));
95*58b9f456SAndroid Build Coastguard Worker         }
96*58b9f456SAndroid Build Coastguard Worker       }
97*58b9f456SAndroid Build Coastguard Worker     }
98*58b9f456SAndroid Build Coastguard Worker   }
99*58b9f456SAndroid Build Coastguard Worker 
name__anonfb3b86bc0111::Create100*58b9f456SAndroid Build Coastguard Worker   std::string name() const {
101*58b9f456SAndroid Build Coastguard Worker     return "BM_Create" + Access::name() + baseName();
102*58b9f456SAndroid Build Coastguard Worker   }
103*58b9f456SAndroid Build Coastguard Worker };
104*58b9f456SAndroid Build Coastguard Worker 
105*58b9f456SAndroid Build Coastguard Worker template <class Hit, class Access>
106*58b9f456SAndroid Build Coastguard Worker struct Find : Base {
107*58b9f456SAndroid Build Coastguard Worker   using Base::Base;
108*58b9f456SAndroid Build Coastguard Worker 
run__anonfb3b86bc0111::Find109*58b9f456SAndroid Build Coastguard Worker   void run(benchmark::State& State) const {
110*58b9f456SAndroid Build Coastguard Worker     auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access());
111*58b9f456SAndroid Build Coastguard Worker 
112*58b9f456SAndroid Build Coastguard Worker     while (State.KeepRunningBatch(TableSize * NumTables)) {
113*58b9f456SAndroid Build Coastguard Worker       for (auto K : Data.Keys) {
114*58b9f456SAndroid Build Coastguard Worker         for (auto& Set : Data.Sets) {
115*58b9f456SAndroid Build Coastguard Worker           benchmark::DoNotOptimize(Set.find(K));
116*58b9f456SAndroid Build Coastguard Worker         }
117*58b9f456SAndroid Build Coastguard Worker       }
118*58b9f456SAndroid Build Coastguard Worker     }
119*58b9f456SAndroid Build Coastguard Worker   }
120*58b9f456SAndroid Build Coastguard Worker 
name__anonfb3b86bc0111::Find121*58b9f456SAndroid Build Coastguard Worker   std::string name() const {
122*58b9f456SAndroid Build Coastguard Worker     return "BM_Find" + Hit::name() + Access::name() + baseName();
123*58b9f456SAndroid Build Coastguard Worker   }
124*58b9f456SAndroid Build Coastguard Worker };
125*58b9f456SAndroid Build Coastguard Worker 
126*58b9f456SAndroid Build Coastguard Worker template <class Hit, class Access>
127*58b9f456SAndroid Build Coastguard Worker struct FindNeEnd : Base {
128*58b9f456SAndroid Build Coastguard Worker   using Base::Base;
129*58b9f456SAndroid Build Coastguard Worker 
run__anonfb3b86bc0111::FindNeEnd130*58b9f456SAndroid Build Coastguard Worker   void run(benchmark::State& State) const {
131*58b9f456SAndroid Build Coastguard Worker     auto Data = makeTestingSets(TableSize, NumTables, Hit(), Access());
132*58b9f456SAndroid Build Coastguard Worker 
133*58b9f456SAndroid Build Coastguard Worker     while (State.KeepRunningBatch(TableSize * NumTables)) {
134*58b9f456SAndroid Build Coastguard Worker       for (auto K : Data.Keys) {
135*58b9f456SAndroid Build Coastguard Worker         for (auto& Set : Data.Sets) {
136*58b9f456SAndroid Build Coastguard Worker           benchmark::DoNotOptimize(Set.find(K) != Set.end());
137*58b9f456SAndroid Build Coastguard Worker         }
138*58b9f456SAndroid Build Coastguard Worker       }
139*58b9f456SAndroid Build Coastguard Worker     }
140*58b9f456SAndroid Build Coastguard Worker   }
141*58b9f456SAndroid Build Coastguard Worker 
name__anonfb3b86bc0111::FindNeEnd142*58b9f456SAndroid Build Coastguard Worker   std::string name() const {
143*58b9f456SAndroid Build Coastguard Worker     return "BM_FindNeEnd" + Hit::name() + Access::name() + baseName();
144*58b9f456SAndroid Build Coastguard Worker   }
145*58b9f456SAndroid Build Coastguard Worker };
146*58b9f456SAndroid Build Coastguard Worker 
147*58b9f456SAndroid Build Coastguard Worker template <class Access>
148*58b9f456SAndroid Build Coastguard Worker struct InsertHit : Base {
149*58b9f456SAndroid Build Coastguard Worker   using Base::Base;
150*58b9f456SAndroid Build Coastguard Worker 
run__anonfb3b86bc0111::InsertHit151*58b9f456SAndroid Build Coastguard Worker   void run(benchmark::State& State) const {
152*58b9f456SAndroid Build Coastguard Worker     auto Data = makeTestingSets(TableSize, NumTables, HitType::Hit, Access());
153*58b9f456SAndroid Build Coastguard Worker 
154*58b9f456SAndroid Build Coastguard Worker     while (State.KeepRunningBatch(TableSize * NumTables)) {
155*58b9f456SAndroid Build Coastguard Worker       for (auto K : Data.Keys) {
156*58b9f456SAndroid Build Coastguard Worker         for (auto& Set : Data.Sets) {
157*58b9f456SAndroid Build Coastguard Worker           benchmark::DoNotOptimize(Set.insert(K));
158*58b9f456SAndroid Build Coastguard Worker         }
159*58b9f456SAndroid Build Coastguard Worker       }
160*58b9f456SAndroid Build Coastguard Worker     }
161*58b9f456SAndroid Build Coastguard Worker   }
162*58b9f456SAndroid Build Coastguard Worker 
name__anonfb3b86bc0111::InsertHit163*58b9f456SAndroid Build Coastguard Worker   std::string name() const {
164*58b9f456SAndroid Build Coastguard Worker     return "BM_InsertHit" + Access::name() + baseName();
165*58b9f456SAndroid Build Coastguard Worker   }
166*58b9f456SAndroid Build Coastguard Worker };
167*58b9f456SAndroid Build Coastguard Worker 
168*58b9f456SAndroid Build Coastguard Worker template <class Access>
169*58b9f456SAndroid Build Coastguard Worker struct InsertMissAndErase : Base {
170*58b9f456SAndroid Build Coastguard Worker   using Base::Base;
171*58b9f456SAndroid Build Coastguard Worker 
run__anonfb3b86bc0111::InsertMissAndErase172*58b9f456SAndroid Build Coastguard Worker   void run(benchmark::State& State) const {
173*58b9f456SAndroid Build Coastguard Worker     auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss, Access());
174*58b9f456SAndroid Build Coastguard Worker 
175*58b9f456SAndroid Build Coastguard Worker     while (State.KeepRunningBatch(TableSize * NumTables)) {
176*58b9f456SAndroid Build Coastguard Worker       for (auto K : Data.Keys) {
177*58b9f456SAndroid Build Coastguard Worker         for (auto& Set : Data.Sets) {
178*58b9f456SAndroid Build Coastguard Worker           benchmark::DoNotOptimize(Set.erase(Set.insert(K).first));
179*58b9f456SAndroid Build Coastguard Worker         }
180*58b9f456SAndroid Build Coastguard Worker       }
181*58b9f456SAndroid Build Coastguard Worker     }
182*58b9f456SAndroid Build Coastguard Worker   }
183*58b9f456SAndroid Build Coastguard Worker 
name__anonfb3b86bc0111::InsertMissAndErase184*58b9f456SAndroid Build Coastguard Worker   std::string name() const {
185*58b9f456SAndroid Build Coastguard Worker     return "BM_InsertMissAndErase" + Access::name() + baseName();
186*58b9f456SAndroid Build Coastguard Worker   }
187*58b9f456SAndroid Build Coastguard Worker };
188*58b9f456SAndroid Build Coastguard Worker 
189*58b9f456SAndroid Build Coastguard Worker struct IterateRangeFor : Base {
190*58b9f456SAndroid Build Coastguard Worker   using Base::Base;
191*58b9f456SAndroid Build Coastguard Worker 
run__anonfb3b86bc0111::IterateRangeFor192*58b9f456SAndroid Build Coastguard Worker   void run(benchmark::State& State) const {
193*58b9f456SAndroid Build Coastguard Worker     auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss,
194*58b9f456SAndroid Build Coastguard Worker                                 AccessPattern::Ordered);
195*58b9f456SAndroid Build Coastguard Worker 
196*58b9f456SAndroid Build Coastguard Worker     while (State.KeepRunningBatch(TableSize * NumTables)) {
197*58b9f456SAndroid Build Coastguard Worker       for (auto& Set : Data.Sets) {
198*58b9f456SAndroid Build Coastguard Worker         for (auto& V : Set) {
199*58b9f456SAndroid Build Coastguard Worker           benchmark::DoNotOptimize(V);
200*58b9f456SAndroid Build Coastguard Worker         }
201*58b9f456SAndroid Build Coastguard Worker       }
202*58b9f456SAndroid Build Coastguard Worker     }
203*58b9f456SAndroid Build Coastguard Worker   }
204*58b9f456SAndroid Build Coastguard Worker 
name__anonfb3b86bc0111::IterateRangeFor205*58b9f456SAndroid Build Coastguard Worker   std::string name() const { return "BM_IterateRangeFor" + baseName(); }
206*58b9f456SAndroid Build Coastguard Worker };
207*58b9f456SAndroid Build Coastguard Worker 
208*58b9f456SAndroid Build Coastguard Worker struct IterateBeginEnd : Base {
209*58b9f456SAndroid Build Coastguard Worker   using Base::Base;
210*58b9f456SAndroid Build Coastguard Worker 
run__anonfb3b86bc0111::IterateBeginEnd211*58b9f456SAndroid Build Coastguard Worker   void run(benchmark::State& State) const {
212*58b9f456SAndroid Build Coastguard Worker     auto Data = makeTestingSets(TableSize, NumTables, HitType::Miss,
213*58b9f456SAndroid Build Coastguard Worker                                 AccessPattern::Ordered);
214*58b9f456SAndroid Build Coastguard Worker 
215*58b9f456SAndroid Build Coastguard Worker     while (State.KeepRunningBatch(TableSize * NumTables)) {
216*58b9f456SAndroid Build Coastguard Worker       for (auto& Set : Data.Sets) {
217*58b9f456SAndroid Build Coastguard Worker         for (auto it = Set.begin(); it != Set.end(); ++it) {
218*58b9f456SAndroid Build Coastguard Worker           benchmark::DoNotOptimize(*it);
219*58b9f456SAndroid Build Coastguard Worker         }
220*58b9f456SAndroid Build Coastguard Worker       }
221*58b9f456SAndroid Build Coastguard Worker     }
222*58b9f456SAndroid Build Coastguard Worker   }
223*58b9f456SAndroid Build Coastguard Worker 
name__anonfb3b86bc0111::IterateBeginEnd224*58b9f456SAndroid Build Coastguard Worker   std::string name() const { return "BM_IterateBeginEnd" + baseName(); }
225*58b9f456SAndroid Build Coastguard Worker };
226*58b9f456SAndroid Build Coastguard Worker 
227*58b9f456SAndroid Build Coastguard Worker }  // namespace
228*58b9f456SAndroid Build Coastguard Worker 
main(int argc,char ** argv)229*58b9f456SAndroid Build Coastguard Worker int main(int argc, char** argv) {
230*58b9f456SAndroid Build Coastguard Worker   benchmark::Initialize(&argc, argv);
231*58b9f456SAndroid Build Coastguard Worker   if (benchmark::ReportUnrecognizedArguments(argc, argv))
232*58b9f456SAndroid Build Coastguard Worker     return 1;
233*58b9f456SAndroid Build Coastguard Worker 
234*58b9f456SAndroid Build Coastguard Worker   const std::vector<size_t> TableSize{1, 10, 100, 1000, 10000, 100000, 1000000};
235*58b9f456SAndroid Build Coastguard Worker   const std::vector<size_t> NumTables{1, 10, 100, 1000, 10000, 100000, 1000000};
236*58b9f456SAndroid Build Coastguard Worker 
237*58b9f456SAndroid Build Coastguard Worker   makeCartesianProductBenchmark<Create, AllAccessPattern>(TableSize, NumTables);
238*58b9f456SAndroid Build Coastguard Worker   makeCartesianProductBenchmark<Find, AllHitTypes, AllAccessPattern>(
239*58b9f456SAndroid Build Coastguard Worker       TableSize, NumTables);
240*58b9f456SAndroid Build Coastguard Worker   makeCartesianProductBenchmark<FindNeEnd, AllHitTypes, AllAccessPattern>(
241*58b9f456SAndroid Build Coastguard Worker       TableSize, NumTables);
242*58b9f456SAndroid Build Coastguard Worker   makeCartesianProductBenchmark<InsertHit, AllAccessPattern>(
243*58b9f456SAndroid Build Coastguard Worker       TableSize, NumTables);
244*58b9f456SAndroid Build Coastguard Worker   makeCartesianProductBenchmark<InsertMissAndErase, AllAccessPattern>(
245*58b9f456SAndroid Build Coastguard Worker       TableSize, NumTables);
246*58b9f456SAndroid Build Coastguard Worker   makeCartesianProductBenchmark<IterateRangeFor>(TableSize, NumTables);
247*58b9f456SAndroid Build Coastguard Worker   makeCartesianProductBenchmark<IterateBeginEnd>(TableSize, NumTables);
248*58b9f456SAndroid Build Coastguard Worker   benchmark::RunSpecifiedBenchmarks();
249*58b9f456SAndroid Build Coastguard Worker }
250