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