CompactProtocol: readVarint optimizations
authorAlex Landau <alandau@fb.com>
Fri, 14 Nov 2014 04:50:30 +0000 (20:50 -0800)
committerDave Watson <davejwatson@fb.com>
Wed, 19 Nov 2014 20:52:36 +0000 (12:52 -0800)
Summary:
* Unroll readVarint() - no loops in the fast path
* Split Cursor::skip() into fast and slow paths

Test Plan:
```
------ old ------   ------ new ------
Benchmark                               time/iter  iters/s  time/iter  iters/s        win
=========================================================================================
CompactProtocol_read_Empty                13.21ns   75.69M    13.21ns   75.71M      0.03%
CompactProtocol_read_SmallInt             29.95ns   33.39M    28.96ns   34.53M      3.41%
CompactProtocol_read_BigInt               67.83ns   14.74M    36.77ns   27.19M     84.46%
CompactProtocol_read_SmallString          55.72ns   17.95M    54.04ns   18.50M      3.06%
CompactProtocol_read_BigString           342.93ns    2.92M   332.18ns    3.01M      3.08%
CompactProtocol_read_BigBinary           186.18ns    5.37M   181.45ns    5.51M      2.61%
CompactProtocol_read_LargeBinary         190.65ns    5.25M   184.85ns    5.41M      3.05%
CompactProtocol_read_Mixed               101.97ns    9.81M    97.06ns   10.30M      4.99%
CompactProtocol_read_SmallListInt        148.09ns    6.75M   139.52ns    7.17M      6.22%
CompactProtocol_read_BigListInt           71.69us   13.95K    63.34us   15.79K     13.19%
CompactProtocol_read_BigListMixed          1.26ms   790.67     1.18ms   845.66      6.95%
CompactProtocol_read_LargeListMixed      139.80ms     7.15   134.68ms     7.42      3.78%
```

Reviewed By: davejwatson@fb.com

Subscribers: trunkagent, alandau, bmatheny, njormrod, mshneer, folly-diffs@

FB internal diff: D1681244

Signature: t1:1681244:1416265579:f630c53f9c31788f847d0af72198bbd9e5ea43f1

folly/io/Cursor.h

index c9a342eb8b4a6354af41eb3ca430459e8de6f37d..803efc66bdfb3d43ea44f99f692c518df5d3ab7f 100644 (file)
@@ -274,9 +274,11 @@ class CursorBase {
   }
 
   void skip(size_t len) {
-    if (UNLIKELY(skipAtMost(len) != len)) {
-      throw std::out_of_range("underflow");
+    if (LIKELY(length() >= len)) {
+      offset_ += len;
+      return;
     }
+    skipSlow(len);
   }
 
   size_t pullAtMost(void* buf, size_t len) {
@@ -447,6 +449,12 @@ class CursorBase {
   void advanceDone() {
   }
 
+  void skipSlow(size_t len) {
+    if (UNLIKELY(skipAtMost(len) != len)) {
+      throw std::out_of_range("underflow");
+    }
+  }
+
   BufType* buffer_;
 };