• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <filesystem>
2 
3 #include "GenerateInput.h"
4 #include "benchmark/benchmark.h"
5 #include "test_iterators.h"
6 
7 namespace fs = std::filesystem;
8 
9 static const size_t TestNumInputs = 1024;
10 
11 template <class GenInputs>
BM_PathConstructString(benchmark::State & st,GenInputs gen)12 void BM_PathConstructString(benchmark::State& st, GenInputs gen) {
13   using fs::path;
14   const auto in = gen(st.range(0));
15   path PP;
16   for (auto& Part : in)
17     PP /= Part;
18   benchmark::DoNotOptimize(PP.native().data());
19   while (st.KeepRunning()) {
20     const path P(PP.native());
21     benchmark::DoNotOptimize(P.native().data());
22   }
23   st.SetComplexityN(st.range(0));
24 }
25 BENCHMARK_CAPTURE(BM_PathConstructString, large_string, getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
26 
27 template <class GenInputs>
BM_PathConstructCStr(benchmark::State & st,GenInputs gen)28 void BM_PathConstructCStr(benchmark::State& st, GenInputs gen) {
29   using fs::path;
30   const auto in = gen(st.range(0));
31   path PP;
32   for (auto& Part : in)
33     PP /= Part;
34   benchmark::DoNotOptimize(PP.native().data());
35   while (st.KeepRunning()) {
36     const path P(PP.native().c_str());
37     benchmark::DoNotOptimize(P.native().data());
38   }
39 }
40 BENCHMARK_CAPTURE(BM_PathConstructCStr, large_string, getRandomStringInputs)->Arg(TestNumInputs);
41 
42 template <template <class...> class ItType, class GenInputs>
BM_PathConstructIter(benchmark::State & st,GenInputs gen)43 void BM_PathConstructIter(benchmark::State& st, GenInputs gen) {
44   using fs::path;
45   using Iter    = ItType<std::string::const_iterator>;
46   const auto in = gen(st.range(0));
47   path PP;
48   for (auto& Part : in)
49     PP /= Part;
50   auto Start = Iter(PP.native().begin());
51   auto End   = Iter(PP.native().end());
52   benchmark::DoNotOptimize(PP.native().data());
53   benchmark::DoNotOptimize(Start);
54   benchmark::DoNotOptimize(End);
55   while (st.KeepRunning()) {
56     const path P(Start, End);
57     benchmark::DoNotOptimize(P.native().data());
58   }
59   st.SetComplexityN(st.range(0));
60 }
61 template <class GenInputs>
BM_PathConstructInputIter(benchmark::State & st,GenInputs gen)62 void BM_PathConstructInputIter(benchmark::State& st, GenInputs gen) {
63   BM_PathConstructIter<cpp17_input_iterator>(st, gen);
64 }
65 template <class GenInputs>
BM_PathConstructForwardIter(benchmark::State & st,GenInputs gen)66 void BM_PathConstructForwardIter(benchmark::State& st, GenInputs gen) {
67   BM_PathConstructIter<forward_iterator>(st, gen);
68 }
69 BENCHMARK_CAPTURE(BM_PathConstructInputIter, large_string, getRandomStringInputs)
70     ->Range(8, TestNumInputs)
71     ->Complexity();
72 BENCHMARK_CAPTURE(BM_PathConstructForwardIter, large_string, getRandomStringInputs)
73     ->Range(8, TestNumInputs)
74     ->Complexity();
75 
76 template <class GenInputs>
BM_PathIterateMultipleTimes(benchmark::State & st,GenInputs gen)77 void BM_PathIterateMultipleTimes(benchmark::State& st, GenInputs gen) {
78   using fs::path;
79   const auto in = gen(st.range(0));
80   path PP;
81   for (auto& Part : in)
82     PP /= Part;
83   benchmark::DoNotOptimize(PP.native().data());
84   while (st.KeepRunning()) {
85     for (auto const& E : PP) {
86       benchmark::DoNotOptimize(E.native().data());
87     }
88     benchmark::ClobberMemory();
89   }
90   st.SetComplexityN(st.range(0));
91 }
92 BENCHMARK_CAPTURE(BM_PathIterateMultipleTimes, iterate_elements, getRandomStringInputs)
93     ->Range(8, TestNumInputs)
94     ->Complexity();
95 
96 template <class GenInputs>
BM_PathIterateOnce(benchmark::State & st,GenInputs gen)97 void BM_PathIterateOnce(benchmark::State& st, GenInputs gen) {
98   using fs::path;
99   const auto in = gen(st.range(0));
100   path PP;
101   for (auto& Part : in)
102     PP /= Part;
103   benchmark::DoNotOptimize(PP.native().data());
104   while (st.KeepRunning()) {
105     const path P = PP.native();
106     for (auto const& E : P) {
107       benchmark::DoNotOptimize(E.native().data());
108     }
109     benchmark::ClobberMemory();
110   }
111   st.SetComplexityN(st.range(0));
112 }
113 BENCHMARK_CAPTURE(BM_PathIterateOnce, iterate_elements, getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
114 
115 template <class GenInputs>
BM_PathIterateOnceBackwards(benchmark::State & st,GenInputs gen)116 void BM_PathIterateOnceBackwards(benchmark::State& st, GenInputs gen) {
117   using fs::path;
118   const auto in = gen(st.range(0));
119   path PP;
120   for (auto& Part : in)
121     PP /= Part;
122   benchmark::DoNotOptimize(PP.native().data());
123   while (st.KeepRunning()) {
124     const path P = PP.native();
125     const auto B = P.begin();
126     auto I       = P.end();
127     while (I != B) {
128       --I;
129       benchmark::DoNotOptimize(*I);
130     }
131     benchmark::DoNotOptimize(*I);
132   }
133 }
134 BENCHMARK_CAPTURE(BM_PathIterateOnceBackwards, iterate_elements, getRandomStringInputs)->Arg(TestNumInputs);
135 
getRandomPaths(int NumParts,int PathLen)136 static fs::path getRandomPaths(int NumParts, int PathLen) {
137   fs::path Result;
138   while (NumParts--) {
139     std::string Part = getRandomString(PathLen);
140     Result /= Part;
141   }
142   return Result;
143 }
144 
145 template <class GenInput>
BM_LexicallyNormal(benchmark::State & st,GenInput gen,size_t PathLen)146 void BM_LexicallyNormal(benchmark::State& st, GenInput gen, size_t PathLen) {
147   using fs::path;
148   auto In = gen(st.range(0), PathLen);
149   benchmark::DoNotOptimize(&In);
150   while (st.KeepRunning()) {
151     benchmark::DoNotOptimize(In.lexically_normal());
152   }
153   st.SetComplexityN(st.range(0));
154 }
155 BENCHMARK_CAPTURE(BM_LexicallyNormal, small_path, getRandomPaths, /*PathLen*/ 5)
156     ->RangeMultiplier(2)
157     ->Range(2, 256)
158     ->Complexity();
159 BENCHMARK_CAPTURE(BM_LexicallyNormal, large_path, getRandomPaths, /*PathLen*/ 32)
160     ->RangeMultiplier(2)
161     ->Range(2, 256)
162     ->Complexity();
163 
164 BENCHMARK_MAIN();
165