146035553Spatrick #include "benchmark/benchmark.h"
246035553Spatrick #include "GenerateInput.h"
346035553Spatrick #include "test_iterators.h"
446035553Spatrick #include "filesystem_include.h"
546035553Spatrick
646035553Spatrick static const size_t TestNumInputs = 1024;
746035553Spatrick
846035553Spatrick
946035553Spatrick template <class GenInputs>
BM_PathConstructString(benchmark::State & st,GenInputs gen)1046035553Spatrick void BM_PathConstructString(benchmark::State &st, GenInputs gen) {
1146035553Spatrick using fs::path;
1246035553Spatrick const auto in = gen(st.range(0));
1346035553Spatrick path PP;
1446035553Spatrick for (auto& Part : in)
1546035553Spatrick PP /= Part;
1646035553Spatrick benchmark::DoNotOptimize(PP.native().data());
1746035553Spatrick while (st.KeepRunning()) {
1846035553Spatrick const path P(PP.native());
1946035553Spatrick benchmark::DoNotOptimize(P.native().data());
2046035553Spatrick }
2146035553Spatrick st.SetComplexityN(st.range(0));
2246035553Spatrick }
2346035553Spatrick BENCHMARK_CAPTURE(BM_PathConstructString, large_string,
2446035553Spatrick getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
2546035553Spatrick
2646035553Spatrick
2746035553Spatrick template <class GenInputs>
BM_PathConstructCStr(benchmark::State & st,GenInputs gen)2846035553Spatrick void BM_PathConstructCStr(benchmark::State &st, GenInputs gen) {
2946035553Spatrick using fs::path;
3046035553Spatrick const auto in = gen(st.range(0));
3146035553Spatrick path PP;
3246035553Spatrick for (auto& Part : in)
3346035553Spatrick PP /= Part;
3446035553Spatrick benchmark::DoNotOptimize(PP.native().data());
3546035553Spatrick while (st.KeepRunning()) {
3646035553Spatrick const path P(PP.native().c_str());
3746035553Spatrick benchmark::DoNotOptimize(P.native().data());
3846035553Spatrick }
3946035553Spatrick }
4046035553Spatrick BENCHMARK_CAPTURE(BM_PathConstructCStr, large_string,
4146035553Spatrick getRandomStringInputs)->Arg(TestNumInputs);
4246035553Spatrick
4346035553Spatrick
4446035553Spatrick template <template <class...> class ItType, class GenInputs>
BM_PathConstructIter(benchmark::State & st,GenInputs gen)4546035553Spatrick void BM_PathConstructIter(benchmark::State &st, GenInputs gen) {
4646035553Spatrick using fs::path;
4746035553Spatrick using Iter = ItType<std::string::const_iterator>;
4846035553Spatrick const auto in = gen(st.range(0));
4946035553Spatrick path PP;
5046035553Spatrick for (auto& Part : in)
5146035553Spatrick PP /= Part;
5246035553Spatrick auto Start = Iter(PP.native().begin());
5346035553Spatrick auto End = Iter(PP.native().end());
5446035553Spatrick benchmark::DoNotOptimize(PP.native().data());
5546035553Spatrick benchmark::DoNotOptimize(Start);
5646035553Spatrick benchmark::DoNotOptimize(End);
5746035553Spatrick while (st.KeepRunning()) {
5846035553Spatrick const path P(Start, End);
5946035553Spatrick benchmark::DoNotOptimize(P.native().data());
6046035553Spatrick }
6146035553Spatrick st.SetComplexityN(st.range(0));
6246035553Spatrick }
6346035553Spatrick template <class GenInputs>
BM_PathConstructInputIter(benchmark::State & st,GenInputs gen)6446035553Spatrick void BM_PathConstructInputIter(benchmark::State &st, GenInputs gen) {
6576d0caaeSpatrick BM_PathConstructIter<cpp17_input_iterator>(st, gen);
6646035553Spatrick }
6746035553Spatrick template <class GenInputs>
BM_PathConstructForwardIter(benchmark::State & st,GenInputs gen)6846035553Spatrick void BM_PathConstructForwardIter(benchmark::State &st, GenInputs gen) {
6946035553Spatrick BM_PathConstructIter<forward_iterator>(st, gen);
7046035553Spatrick }
7146035553Spatrick BENCHMARK_CAPTURE(BM_PathConstructInputIter, large_string,
7246035553Spatrick getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
7346035553Spatrick BENCHMARK_CAPTURE(BM_PathConstructForwardIter, large_string,
7446035553Spatrick getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
7546035553Spatrick
7646035553Spatrick
7746035553Spatrick template <class GenInputs>
BM_PathIterateMultipleTimes(benchmark::State & st,GenInputs gen)7846035553Spatrick void BM_PathIterateMultipleTimes(benchmark::State &st, GenInputs gen) {
7946035553Spatrick using fs::path;
8046035553Spatrick const auto in = gen(st.range(0));
8146035553Spatrick path PP;
8246035553Spatrick for (auto& Part : in)
8346035553Spatrick PP /= Part;
8446035553Spatrick benchmark::DoNotOptimize(PP.native().data());
8546035553Spatrick while (st.KeepRunning()) {
86*4bdff4beSrobert for (auto const& E : PP) {
8746035553Spatrick benchmark::DoNotOptimize(E.native().data());
8846035553Spatrick }
8946035553Spatrick benchmark::ClobberMemory();
9046035553Spatrick }
9146035553Spatrick st.SetComplexityN(st.range(0));
9246035553Spatrick }
9346035553Spatrick BENCHMARK_CAPTURE(BM_PathIterateMultipleTimes, iterate_elements,
9446035553Spatrick getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
9546035553Spatrick
9646035553Spatrick
9746035553Spatrick template <class GenInputs>
BM_PathIterateOnce(benchmark::State & st,GenInputs gen)9846035553Spatrick void BM_PathIterateOnce(benchmark::State &st, GenInputs gen) {
9946035553Spatrick using fs::path;
10046035553Spatrick const auto in = gen(st.range(0));
10146035553Spatrick path PP;
10246035553Spatrick for (auto& Part : in)
10346035553Spatrick PP /= Part;
10446035553Spatrick benchmark::DoNotOptimize(PP.native().data());
10546035553Spatrick while (st.KeepRunning()) {
10646035553Spatrick const path P = PP.native();
107*4bdff4beSrobert for (auto const& E : P) {
10846035553Spatrick benchmark::DoNotOptimize(E.native().data());
10946035553Spatrick }
11046035553Spatrick benchmark::ClobberMemory();
11146035553Spatrick }
11246035553Spatrick st.SetComplexityN(st.range(0));
11346035553Spatrick }
11446035553Spatrick BENCHMARK_CAPTURE(BM_PathIterateOnce, iterate_elements,
11546035553Spatrick getRandomStringInputs)->Range(8, TestNumInputs)->Complexity();
11646035553Spatrick
11746035553Spatrick template <class GenInputs>
BM_PathIterateOnceBackwards(benchmark::State & st,GenInputs gen)11846035553Spatrick void BM_PathIterateOnceBackwards(benchmark::State &st, GenInputs gen) {
11946035553Spatrick using fs::path;
12046035553Spatrick const auto in = gen(st.range(0));
12146035553Spatrick path PP;
12246035553Spatrick for (auto& Part : in)
12346035553Spatrick PP /= Part;
12446035553Spatrick benchmark::DoNotOptimize(PP.native().data());
12546035553Spatrick while (st.KeepRunning()) {
12646035553Spatrick const path P = PP.native();
12746035553Spatrick const auto B = P.begin();
12846035553Spatrick auto I = P.end();
12946035553Spatrick while (I != B) {
13046035553Spatrick --I;
13146035553Spatrick benchmark::DoNotOptimize(*I);
13246035553Spatrick }
13346035553Spatrick benchmark::DoNotOptimize(*I);
13446035553Spatrick }
13546035553Spatrick }
13646035553Spatrick BENCHMARK_CAPTURE(BM_PathIterateOnceBackwards, iterate_elements,
13746035553Spatrick getRandomStringInputs)->Arg(TestNumInputs);
13846035553Spatrick
getRandomPaths(int NumParts,int PathLen)13946035553Spatrick static fs::path getRandomPaths(int NumParts, int PathLen) {
14046035553Spatrick fs::path Result;
14146035553Spatrick while (NumParts--) {
14246035553Spatrick std::string Part = getRandomString(PathLen);
14346035553Spatrick Result /= Part;
14446035553Spatrick }
14546035553Spatrick return Result;
14646035553Spatrick }
14746035553Spatrick
14846035553Spatrick template <class GenInput>
BM_LexicallyNormal(benchmark::State & st,GenInput gen,size_t PathLen)14946035553Spatrick void BM_LexicallyNormal(benchmark::State &st, GenInput gen, size_t PathLen) {
15046035553Spatrick using fs::path;
15146035553Spatrick auto In = gen(st.range(0), PathLen);
15246035553Spatrick benchmark::DoNotOptimize(&In);
15346035553Spatrick while (st.KeepRunning()) {
15446035553Spatrick benchmark::DoNotOptimize(In.lexically_normal());
15546035553Spatrick }
15646035553Spatrick st.SetComplexityN(st.range(0));
15746035553Spatrick }
15846035553Spatrick BENCHMARK_CAPTURE(BM_LexicallyNormal, small_path,
15946035553Spatrick getRandomPaths, /*PathLen*/5)->RangeMultiplier(2)->Range(2, 256)->Complexity();
16046035553Spatrick BENCHMARK_CAPTURE(BM_LexicallyNormal, large_path,
16146035553Spatrick getRandomPaths, /*PathLen*/32)->RangeMultiplier(2)->Range(2, 256)->Complexity();
16246035553Spatrick
16346035553Spatrick BENCHMARK_MAIN();
164