From 22b02d5f8cb26f973e1ac2632ac8ac4c095ab02a Mon Sep 17 00:00:00 2001 From: Alex Landau Date: Wed, 12 Nov 2014 17:19:15 -0800 Subject: [PATCH 1/1] CompactProtocol: more improvements Summary: Add a specialized Cursor method that reads exactly 1 byte, in addition to the existing one that reads into a buffer. Use it when reading varints and standalone bytes in a CompactProtocol struct. Test Plan: ``` ------ old ------ ------ new ------ Benchmark time/iter iters/s time/iter iters/s win ========================================================================================= CompactProtocol_read_Empty 18.68ns 53.54M 13.21ns 75.69M 41.37% CompactProtocol_read_SmallInt 42.60ns 23.47M 29.95ns 33.39M 42.27% CompactProtocol_read_BigInt 83.62ns 11.96M 68.40ns 14.62M 22.24% CompactProtocol_read_SmallString 67.33ns 14.85M 55.62ns 17.98M 21.08% CompactProtocol_read_BigString 353.83ns 2.83M 330.19ns 3.03M 7.07% CompactProtocol_read_BigBinary 190.82ns 5.24M 182.90ns 5.47M 4.39% CompactProtocol_read_LargeBinary 200.95ns 4.98M 187.00ns 5.35M 7.43% CompactProtocol_read_Mixed 137.42ns 7.28M 102.98ns 9.71M 33.38% CompactProtocol_read_SmallListInt 203.98ns 4.90M 146.68ns 6.82M 39.18% CompactProtocol_read_BigListInt 120.50us 8.30K 71.56us 13.97K 68.31% CompactProtocol_read_BigListMixed 1.62ms 617.07 1.26ms 795.60 28.93% CompactProtocol_read_LargeListMixed 177.50ms 5.63 140.73ms 7.11 26.29% ``` Reviewed By: haijunz@fb.com Subscribers: trunkagent, alandau, bmatheny, njormrod, mshneer, folly-diffs@ FB internal diff: D1678077 Signature: t1:1678077:1415923409:22accee6b62b6e2bf471f3758a290f71978a8c4e --- folly/io/Cursor.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/folly/io/Cursor.h b/folly/io/Cursor.h index 6ae8aef3..c9a342eb 100644 --- a/folly/io/Cursor.h +++ b/folly/io/Cursor.h @@ -236,6 +236,25 @@ class CursorBase { return std::make_pair(data(), available); } + /** + * Read one byte. Equivalent to pull(&byte, 1) but faster. + */ + uint8_t pullByte() { + // fast path + if (LIKELY(length() >= 1)) { + uint8_t byte = *data(); + offset_++; + return byte; + } + + // slow path + uint8_t byte; + if (UNLIKELY(pullAtMost(&byte, 1) != 1)) { + throw std::out_of_range("underflow"); + } + return byte; + } + void pull(void* buf, size_t len) { if (UNLIKELY(pullAtMost(buf, len) != len)) { throw std::out_of_range("underflow"); -- 2.34.1