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