Short-circuit operator== based on size()
authorTom Jackson <tjackson@fb.com>
Wed, 13 Mar 2013 22:44:59 +0000 (15:44 -0700)
committerJordan DeLong <jdelong@fb.com>
Tue, 19 Mar 2013 00:09:22 +0000 (17:09 -0700)
Summary:
We don't do this today, but it looks like std::string does. For longer, similar strings, this is a big win.

Before:

```lang=text
============================================================================
./folly/test/FBStringTestBenchmarks.cpp.h       relative  time/iter  iters/s
============================================================================
BM_equality_string(65536)                                    5.13ms   194.87
BM_equality_fbstring(65536)                                 11.34ms    88.18
============================================================================
```

After:

```lang=text
============================================================================
./folly/test/FBStringTestBenchmarks.cpp.h       relative  time/iter  iters/s
============================================================================
BM_equality_string(65536)                                    5.01ms   199.74
BM_equality_fbstring(65536)                                  6.63ms   150.78
============================================================================
```

Test Plan: Benchmark, unit  tests

Reviewed By: tudorb@fb.com

FB internal diff: D737482

folly/FBString.h
folly/test/FBStringBenchmark.cpp
folly/test/FBStringTestBenchmarks.cpp.h

index 7c465870e9fad0a03c5731e448b2019a36b37b9f..e0c5625084a93ca391b80b5dac8395d6029ad552 100644 (file)
@@ -2053,7 +2053,7 @@ template <typename E, class T, class A, class S>
 inline
 bool operator==(const basic_fbstring<E, T, A, S>& lhs,
                 const basic_fbstring<E, T, A, S>& rhs) {
-  return lhs.compare(rhs) == 0; }
+  return lhs.size() == rhs.size() && lhs.compare(rhs) == 0; }
 
 template <typename E, class T, class A, class S>
 inline
index 65fb652505b1fd9f0b1926a49ac5a285e44e5487..e9cd297b6a074ac02b1d45c8004ad12cf4fe8328 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2013 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -56,6 +56,15 @@ void randomString(String* toFill, unsigned int maxSize = 1000) {
   }
 }
 
+template <class String>
+void randomBinaryString(String* toFill, unsigned int maxSize = 1000) {
+  assert(toFill);
+  toFill->resize(random(0, maxSize));
+  FOR_EACH (i, *toFill) {
+    *i = random('0', '1');
+  }
+}
+
 template <class String, class Integral>
 void Num2String(String& str, Integral n) {
   str.resize(30, '\0');
index 1e29ed29e60bf93ae1bc6c9cb9b4b19085e507df..9726fb7eb6ac36dc2b990fb2fdf9bef7294d349d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2013 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -190,6 +190,23 @@ expect to get a call for an interview.";
 }
 BENCHMARK_PARAM(BENCHFUN(findUnsuccessful), 524288);
 
+void BENCHFUN(equality)(int iters, int arg) {
+  std::vector<STRING> haystack(arg);
+
+  BENCHMARK_SUSPEND {
+    for (auto& hay : haystack) {
+      randomBinaryString(&hay, 1024);
+    }
+  }
+
+  FOR_EACH_RANGE (i, 0, iters) {
+    STRING needle;
+    randomBinaryString(&needle, 1024);
+    doNotOptimizeAway(std::find(haystack.begin(), haystack.end(), needle));
+  }
+}
+BENCHMARK_PARAM(BENCHFUN(equality), 65536);
+
 void BENCHFUN(replace)(int iters, int arg) {
   STRING s;
   BENCHMARK_SUSPEND {