Update StringKeyed... benchmarks to tell the whole story
authorPhil Willoughby <philwill@fb.com>
Thu, 6 Apr 2017 11:03:02 +0000 (04:03 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Thu, 6 Apr 2017 11:06:55 +0000 (04:06 -0700)
Summary:
Benchmark each type with its native key type and with its non-native key type.
This allows you to make a more-informed decision about which to use based on
the types you have available at insertion/lookup time.

Reviewed By: yfeldblum

Differential Revision: D4826527

fbshipit-source-id: ee4ef5255d2bdd955e9deb30dc4c28be183cee07

folly/experimental/test/StringKeyedBenchmark.cpp

index 7002a2f9ade64d35f543813d024767c41cdcb64c..7c66ed5130a56f563907f7fb2a4036b19ade9a03 100644 (file)
@@ -16,6 +16,7 @@
 // Copyright 2013-present Facebook. All Rights Reserved.
 
 #include <folly/Benchmark.h>
+#include <folly/Conv.h>
 #include <folly/Range.h>
 
 #include <map>
@@ -35,11 +36,12 @@ using folly::StringKeyedUnorderedMap;
 using folly::StringKeyedUnorderedSet;
 using folly::StringPiece;
 using std::map;
-using std::to_string;
+using folly::to;
 using std::set;
 using std::string;
 using std::unordered_map;
 using std::unordered_set;
+using namespace std::string_literals;
 
 static map<string, int> m;
 static StringKeyedMap<int> skm;
@@ -49,96 +51,204 @@ static unordered_map<string, int> um;
 static StringKeyedUnorderedMap<int> skum;
 static unordered_set<string> us;
 static StringKeyedUnorderedSet skus;
-static const string lookup("123");
-static const folly::StringPiece lookupPiece(lookup);
+static const std::string lookup = "1234567890abcdefghijklmnopqrstuvwxyz"s;
+static const folly::StringPiece lookupPiece{
+    "1234567890abcdefghijklmnopqrstuvwxyz"};
+
+#if !defined(FOLLY_HAVE_COMPARE_EQUIVALENT) && _LIBCPP_VERSION >= 3400
+#define FOLLY_HAVE_COMPARE_EQUIVALENT 1
+#endif
+
+#if !defined(FOLLY_HAVE_COMPARE_EQUIVALENT) && __GNUC__ >= 5
+#define FOLLY_HAVE_COMPARE_EQUIVALENT 1
+#endif
+
+#if FOLLY_HAVE_COMPARE_EQUIVALENT
+static map<string, int, std::less<void>> m_equiv;
+static set<string, std::less<void>> s_equiv;
+#endif
 
 static void initBenchmarks() {
   for (int i = 0; i < 1000; ++i) {
-    auto iStr = to_string(i);
+    auto iStr = to<string>(i);
     m[iStr] = i;
-    skm.insert(make_pair(iStr, i));
-    um[iStr] = i;
-    skum.insert(make_pair(iStr, i));
     s.insert(iStr);
-    sks.insert(iStr);
-    us.insert(iStr);
-    skus.insert(iStr);
   }
+  m.insert(make_pair(lookup, 0));
+  s.insert(lookup);
+
+  skm = decltype(skm){m.begin(), m.end()};
+  um = decltype(um){m.begin(), m.end()};
+  skum = decltype(skum){m.begin(), m.end()};
+
+  sks = decltype(sks){s.begin(), s.end()};
+  us = decltype(us){s.begin(), s.end()};
+  skus = decltype(skus){s.begin(), s.end()};
+#if FOLLY_HAVE_COMPARE_EQUIVALENT
+  m_equiv = decltype(m_equiv){m.begin(), m.end()};
+  s_equiv = decltype(s_equiv){s.begin(), s.end()};
+#endif
 }
 
-BENCHMARK(std_map_benchmark_find) {
+BENCHMARK(std_map_benchmark_find_native) {
+  folly::doNotOptimizeAway(m.find(lookup)->second);
+}
+
+BENCHMARK_RELATIVE(std_map_benchmark_find_cross) {
   folly::doNotOptimizeAway(m.find(lookupPiece.str())->second);
 }
 
-BENCHMARK_RELATIVE(sk_map_benchmark_find) {
+#if FOLLY_HAVE_COMPARE_EQUIVALENT
+BENCHMARK_RELATIVE(std_map_benchmark_find_equiv) {
+  folly::doNotOptimizeAway(m_equiv.find(lookupPiece)->second);
+}
+#endif
+
+BENCHMARK_RELATIVE(sk_map_benchmark_find_native) {
   folly::doNotOptimizeAway(skm.find(lookupPiece)->second);
 }
 
-BENCHMARK(std_map_benchmark_erase_emplace) {
+BENCHMARK_RELATIVE(sk_map_benchmark_find_cross) {
+  folly::doNotOptimizeAway(skm.find(lookup)->second);
+}
+
+BENCHMARK(std_map_benchmark_erase_emplace_native) {
   m.erase(lookup);
   m.emplace(lookup, 123);
 }
 
-BENCHMARK_RELATIVE(sk_map_benchmark_erase_emplace) {
+BENCHMARK_RELATIVE(std_map_benchmark_erase_emplace_cross) {
+  m.erase(lookupPiece.str());
+  m.emplace(lookupPiece.str(), 123);
+}
+
+BENCHMARK_RELATIVE(sk_map_benchmark_erase_emplace_native) {
+  skm.erase(lookupPiece);
+  skm.emplace(lookupPiece, 123);
+}
+
+BENCHMARK_RELATIVE(sk_map_benchmark_erase_emplace_cross) {
   skm.erase(lookup);
   skm.emplace(lookup, 123);
 }
 
-BENCHMARK(std_unordered_map_benchmark_find) {
+BENCHMARK(std_unordered_map_benchmark_find_native) {
+  folly::doNotOptimizeAway(um.find(lookup)->second);
+}
+
+BENCHMARK_RELATIVE(std_unordered_map_benchmark_find_cross) {
   folly::doNotOptimizeAway(um.find(lookupPiece.str())->second);
 }
 
-BENCHMARK_RELATIVE(sk_unordered_map_benchmark_find) {
+BENCHMARK_RELATIVE(sk_unordered_map_benchmark_find_native) {
   folly::doNotOptimizeAway(skum.find(lookupPiece)->second);
 }
 
-BENCHMARK(std_unordered_map_benchmark_erase_emplace) {
+BENCHMARK_RELATIVE(sk_unordered_map_benchmark_find_cross) {
+  folly::doNotOptimizeAway(skum.find(lookup)->second);
+}
+
+BENCHMARK(std_unordered_map_benchmark_erase_emplace_native) {
   um.erase(lookup);
   um.emplace(lookup, 123);
 }
 
-BENCHMARK_RELATIVE(sk_unordered_map_benchmark_erase_emplace) {
+BENCHMARK_RELATIVE(std_unordered_map_benchmark_erase_emplace_cross) {
+  um.erase(lookupPiece.str());
+  um.emplace(lookupPiece.str(), 123);
+}
+
+BENCHMARK_RELATIVE(sk_unordered_map_benchmark_erase_emplace_native) {
+  skum.erase(lookupPiece);
+  skum.emplace(lookupPiece, 123);
+}
+
+BENCHMARK_RELATIVE(sk_unordered_map_benchmark_erase_emplace_cross) {
   skum.erase(lookup);
   skum.emplace(lookup, 123);
 }
 
-BENCHMARK(std_set_benchmark_find) {
+BENCHMARK_DRAW_LINE();
+
+BENCHMARK(std_set_benchmark_find_native) {
+  folly::doNotOptimizeAway(s.find(lookup));
+}
+
+BENCHMARK_RELATIVE(std_set_benchmark_find_cross) {
   folly::doNotOptimizeAway(s.find(lookupPiece.str()));
 }
 
-BENCHMARK_RELATIVE(sk_set_benchmark_find) {
+#if FOLLY_HAVE_COMPARE_EQUIVALENT
+BENCHMARK_RELATIVE(std_set_benchmark_find_equiv) {
+  folly::doNotOptimizeAway(s_equiv.find(lookupPiece));
+}
+#endif
+
+BENCHMARK_RELATIVE(sk_set_benchmark_find_native) {
   folly::doNotOptimizeAway(sks.find(lookupPiece));
 }
 
-BENCHMARK(std_set_benchmark_erase_emplace) {
+BENCHMARK_RELATIVE(sk_set_benchmark_find_cross) {
+  folly::doNotOptimizeAway(sks.find(lookup));
+}
+
+BENCHMARK(std_set_benchmark_erase_emplace_native) {
   s.erase(lookup);
   s.emplace(lookup);
 }
 
-BENCHMARK_RELATIVE(sk_set_benchmark_erase_emplace) {
+BENCHMARK_RELATIVE(std_set_benchmark_erase_emplace_cross) {
+  s.erase(lookupPiece.str());
+  s.emplace(lookupPiece.str());
+}
+
+BENCHMARK_RELATIVE(sk_set_benchmark_erase_emplace_native) {
+  sks.erase(lookupPiece);
+  sks.emplace(lookupPiece);
+}
+
+BENCHMARK_RELATIVE(sk_set_benchmark_erase_emplace_cross) {
   sks.erase(lookup);
   sks.emplace(lookup);
 }
 
-BENCHMARK(std_unordered_set_benchmark_find) {
+BENCHMARK(std_unordered_set_benchmark_find_native) {
+  folly::doNotOptimizeAway(us.find(lookup));
+}
+
+BENCHMARK(std_unordered_set_benchmark_find_cross) {
   folly::doNotOptimizeAway(us.find(lookupPiece.str()));
 }
 
-BENCHMARK_RELATIVE(sk_unordered_set_benchmark_find) {
+BENCHMARK_RELATIVE(sk_unordered_set_benchmark_find_native) {
   folly::doNotOptimizeAway(skus.find(lookupPiece));
 }
 
-BENCHMARK(std_unordered_set_benchmark_erase_emplace) {
+BENCHMARK_RELATIVE(sk_unordered_set_benchmark_find_cross) {
+  folly::doNotOptimizeAway(skus.find(lookup));
+}
+
+BENCHMARK(std_unordered_set_benchmark_erase_emplace_native) {
   us.erase(lookup);
   us.emplace(lookup);
 }
 
-BENCHMARK_RELATIVE(sk_unordered_set_benchmark_erase_emplace) {
+BENCHMARK_RELATIVE(std_unordered_set_benchmark_erase_emplace_cross) {
+  us.erase(lookupPiece.str());
+  us.emplace(lookupPiece.str());
+}
+
+BENCHMARK_RELATIVE(sk_unordered_set_benchmark_erase_emplace_native) {
+  skus.erase(lookupPiece);
+  skus.emplace(lookupPiece);
+}
+
+BENCHMARK_RELATIVE(sk_unordered_set_benchmark_erase_emplace_cross) {
   skus.erase(lookup);
   skus.emplace(lookup);
 }
 
-int main(int argc, char **argv) {
+int main(int argc, char** argv) {
   gflags::ParseCommandLineFlags(&argc, &argv, true);
   initBenchmarks();
   folly::runBenchmarks();