Add start of filesystem benchmarks

llvm-svn: 285524
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 3aa5478e212ced5f0f6ee61359d7ebbe167bbb10
diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt
index 4160157..ed562e0 100644
--- a/benchmarks/CMakeLists.txt
+++ b/benchmarks/CMakeLists.txt
@@ -37,7 +37,14 @@
 #==============================================================================
 # Build Google Benchmark for the native stdlib
 #==============================================================================
-if (LIBCXX_BUILD_BENCHMARK_NATIVE_STDLIB)
+set(BENCHMARK_NATIVE_TARGET_FLAGS)
+if (LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN)
+  set(BENCHMARK_NATIVE_TARGET_FLAGS
+      -gcc-toolchain ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN})
+endif()
+split_list(BENCHMARK_NATIVE_TARGET_FLAGS)
+
+if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
   ExternalProject_Add(google-benchmark-native
         EXCLUDE_FROM_ALL ON
         PREFIX benchmark-native
@@ -46,6 +53,7 @@
         CMAKE_CACHE_ARGS
           -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
           -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
+          -DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_NATIVE_TARGET_FLAGS}
           -DCMAKE_BUILD_TYPE:STRING=RELEASE
           -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
           -DBENCHMARK_ENABLE_TESTING:BOOL=OFF)
@@ -72,12 +80,18 @@
     -nodefaultlibs
     -L${BENCHMARK_LIBCXX_INSTALL}/lib/
 )
+set(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS
+  ${BENCHMARK_NATIVE_TARGET_FLAGS}
+  ${BENCHMARK_TEST_COMPILE_FLAGS}
+)
 set(BENCHMARK_TEST_NATIVE_LINK_FLAGS
-    -L${BENCHMARK_NATIVE_INSTALL}/lib/
+    ${BENCHMARK_NATIVE_TARGET_FLAGS}
+    -L${BENCHMARK_NATIVE_INSTALL}/lib
 )
 split_list(BENCHMARK_TEST_COMPILE_FLAGS)
 split_list(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS)
 split_list(BENCHMARK_TEST_LIBCXX_LINK_FLAGS)
+split_list(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS)
 split_list(BENCHMARK_TEST_NATIVE_LINK_FLAGS)
 macro(add_benchmark_test name source_file)
   set(libcxx_target ${name}_libcxx)
@@ -89,17 +103,25 @@
   else()
     target_link_libraries(${libcxx_target} cxx_static)
   endif()
+  if (TARGET cxx_experimental)
+    target_link_libraries(${libcxx_target} cxx_experimental)
+  endif()
   target_link_libraries(${libcxx_target} -lbenchmark)
   set_target_properties(${libcxx_target}
     PROPERTIES
           OUTPUT_NAME "${name}.libcxx.out"
           COMPILE_FLAGS "${BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS}"
           LINK_FLAGS "${BENCHMARK_TEST_LIBCXX_LINK_FLAGS}")
-  if (LIBCXX_BUILD_BENCHMARK_NATIVE_STDLIB)
+  if (LIBCXX_BENCHMARK_NATIVE_STDLIB)
     set(native_target ${name}_native)
     add_executable(${native_target} EXCLUDE_FROM_ALL ${source_file})
     add_dependencies(${native_target} google-benchmark-native)
     target_link_libraries(${native_target} -lbenchmark)
+    if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++")
+      target_link_libraries(${native_target} -lstdc++fs)
+    elseif (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++")
+      target_link_libraries(${native_target} -lc++experimental)
+    endif()
     if (LIBCXX_HAS_PTHREAD_LIB)
       target_link_libraries(${native_target} -pthread)
     endif()
@@ -108,7 +130,7 @@
       PROPERTIES
           OUTPUT_NAME "${name}.native.out"
           INCLUDE_DIRECTORIES ""
-          COMPILE_FLAGS "${BENCHMARK_TEST_COMPILE_FLAGS}"
+          COMPILE_FLAGS "${BENCHMARK_TEST_NATIVE_COMPILE_FLAGS}"
           LINK_FLAGS "${BENCHMARK_TEST_NATIVE_LINK_FLAGS}")
   endif()
 endmacro()
diff --git a/benchmarks/GenerateInput.hpp b/benchmarks/GenerateInput.hpp
index affd541..9d5adac 100644
--- a/benchmarks/GenerateInput.hpp
+++ b/benchmarks/GenerateInput.hpp
@@ -137,4 +137,6 @@
         cinputs.push_back(str.c_str());
     return cinputs;
 }
+
+
 #endif // BENCHMARK_GENERATE_INPUT_HPP
diff --git a/benchmarks/filesystem.bench.cpp b/benchmarks/filesystem.bench.cpp
new file mode 100644
index 0000000..8dacbe6
--- /dev/null
+++ b/benchmarks/filesystem.bench.cpp
@@ -0,0 +1,90 @@
+#include <experimental/filesystem>
+
+#include "benchmark/benchmark_api.h"
+#include "GenerateInput.hpp"
+
+namespace fs = std::experimental::filesystem;
+
+static const size_t TestNumInputs = 1024;
+
+
+template <class GenInputs>
+void BM_PathConstructString(benchmark::State &st, GenInputs gen) {
+  using namespace fs;
+  const auto in = gen(st.range(0));
+  path PP;
+  for (auto& Part : in)
+    PP /= Part;
+  benchmark::DoNotOptimize(PP.native().data());
+  while (st.KeepRunning()) {
+    const path P(PP.native());
+    benchmark::DoNotOptimize(P.native().data());
+  }
+}
+BENCHMARK_CAPTURE(BM_PathConstructString, iterate_elements,
+  getRandomStringInputs)->Arg(TestNumInputs);
+
+
+template <class GenInputs>
+void BM_PathIterateMultipleTimes(benchmark::State &st, GenInputs gen) {
+  using namespace fs;
+  const auto in = gen(st.range(0));
+  path PP;
+  for (auto& Part : in)
+    PP /= Part;
+  benchmark::DoNotOptimize(PP.native().data());
+  while (st.KeepRunning()) {
+    for (auto &E : PP) {
+      benchmark::DoNotOptimize(E.native().data());
+    }
+    benchmark::ClobberMemory();
+  }
+}
+BENCHMARK_CAPTURE(BM_PathIterateMultipleTimes, iterate_elements,
+  getRandomStringInputs)->Arg(TestNumInputs);
+
+
+template <class GenInputs>
+void BM_PathIterateOnce(benchmark::State &st, GenInputs gen) {
+  using namespace fs;
+  const auto in = gen(st.range(0));
+  path PP;
+  for (auto& Part : in)
+    PP /= Part;
+  benchmark::DoNotOptimize(PP.native().data());
+  while (st.KeepRunning()) {
+    const path P = PP.native();
+    for (auto &E : P) {
+      benchmark::DoNotOptimize(E.native().data());
+    }
+    benchmark::ClobberMemory();
+  }
+}
+BENCHMARK_CAPTURE(BM_PathIterateOnce, iterate_elements,
+  getRandomStringInputs)->Arg(TestNumInputs);
+
+template <class GenInputs>
+void BM_PathIterateOnceBackwards(benchmark::State &st, GenInputs gen) {
+  using namespace fs;
+  const auto in = gen(st.range(0));
+  path PP;
+  for (auto& Part : in)
+    PP /= Part;
+  benchmark::DoNotOptimize(PP.native().data());
+  while (st.KeepRunning()) {
+    const path P = PP.native();
+    const auto B = P.begin();
+    auto I = P.end();
+    while (I != B) {
+      --I;
+      benchmark::DoNotOptimize(*I);
+    }
+    benchmark::DoNotOptimize(*I);
+  }
+}
+BENCHMARK_CAPTURE(BM_PathIterateOnceBackwards, iterate_elements,
+  getRandomStringInputs)->Arg(TestNumInputs);
+
+
+
+BENCHMARK_MAIN()