proxygen
IOBufCursorBenchmark.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <folly/io/IOBuf.h>
18 
19 #include <folly/Benchmark.h>
20 #include <folly/Format.h>
21 #include <folly/Range.h>
22 #include <folly/io/Cursor.h>
23 
25 
26 using folly::ByteRange;
27 using folly::format;
28 using folly::IOBuf;
29 using folly::StringPiece;
30 using std::unique_ptr;
31 using namespace folly::io;
32 
33 int benchmark_size = 1000;
34 unique_ptr<IOBuf> iobuf_benchmark;
35 
36 unique_ptr<IOBuf> iobuf_read_benchmark;
37 
38 template <class CursClass>
39 void runBenchmark() {
40  CursClass c(iobuf_benchmark.get());
41 
42  for (int i = 0; i < benchmark_size; i++) {
43  c.write((uint8_t)0);
44  }
45 }
46 
47 BENCHMARK(rwPrivateCursorBenchmark, iters) {
48  while (iters--) {
49  runBenchmark<RWPrivateCursor>();
50  }
51 }
52 
53 BENCHMARK(rwUnshareCursorBenchmark, iters) {
54  while (iters--) {
55  runBenchmark<RWUnshareCursor>();
56  }
57 }
58 
59 BENCHMARK(cursorBenchmark, iters) {
60  while (iters--) {
61  Cursor c(iobuf_read_benchmark.get());
62  for (int i = 0; i < benchmark_size; i++) {
63  c.read<uint8_t>();
64  }
65  }
66 }
67 
68 BENCHMARK(skipBenchmark, iters) {
69  while (iters--) {
70  Cursor c(iobuf_read_benchmark.get());
71  for (int i = 0; i < benchmark_size; i++) {
72  c.peekBytes();
73  c.skip(1);
74  }
75  }
76 }
77 
78 BENCHMARK(cloneBenchmark, iters) {
79  folly::IOBuf out;
80  while (iters--) {
81  Cursor c(iobuf_read_benchmark.get());
82  for (int i = 0; i < benchmark_size; ++i) {
83  c.clone(out, 1);
84  }
85  }
86 }
87 
88 BENCHMARK(read, iters) {
89  while (iters--) {
90  Cursor c(iobuf_read_benchmark.get());
91  for (int i = 0; i < benchmark_size; ++i) {
92  const auto val = c.read<uint8_t>();
94  }
95  }
96 }
97 
98 BENCHMARK(readSlow, iters) {
99  while (iters--) {
100  Cursor c(iobuf_read_benchmark.get());
101  const int size = benchmark_size / 2;
102  for (int i = 0; i < size; ++i) {
103  const auto val = c.read<uint16_t>();
105  }
106  }
107 }
108 
109 bool prefixBaseline(Cursor& c, const std::array<uint8_t, 4>& expected) {
110  std::array<uint8_t, 4> actual;
111  if (c.pullAtMost(actual.data(), actual.size()) != actual.size()) {
112  return false;
113  }
114  return memcmp(actual.data(), expected.data(), actual.size()) == 0;
115 }
116 
117 bool prefix(Cursor& c, uint32_t expected) {
118  uint32_t actual;
119  if (!c.tryReadLE(actual)) {
120  return false;
121  }
122  return actual == expected;
123 }
124 
126  IOBuf buf{IOBuf::CREATE, 10};
127  buf.append(10);
128  constexpr std::array<uint8_t, 4> prefix = {{0x01, 0x02, 0x03, 0x04}};
129  while (iters--) {
130  for (int i = 0; i < benchmark_size; ++i) {
131  Cursor c(&buf);
132  bool result = prefixBaseline(c, prefix);
133  folly::doNotOptimizeAway(result);
134  }
135  }
136 }
137 
139  IOBuf buf{IOBuf::CREATE, 10};
140  buf.append(10);
141  while (iters--) {
142  for (int i = 0; i < benchmark_size; ++i) {
143  Cursor c(&buf);
144  bool result = prefix(c, 0x01020304);
145  folly::doNotOptimizeAway(result);
146  }
147  }
148 }
149 
166 int main(int argc, char** argv) {
167  gflags::ParseCommandLineFlags(&argc, &argv, true);
168  iobuf_benchmark = IOBuf::create(benchmark_size);
169  iobuf_benchmark->append(benchmark_size);
170 
171  iobuf_read_benchmark = IOBuf::create(1);
172  for (int i = 0; i < benchmark_size; i++) {
173  unique_ptr<IOBuf> iobuf2(IOBuf::create(1));
174  iobuf2->append(1);
175  iobuf_read_benchmark->prependChain(std::move(iobuf2));
176  }
177 
179  return 0;
180 }
int benchmark_size
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
double val
Definition: String.cpp:273
bool prefixBaseline(Cursor &c, const std::array< uint8_t, 4 > &expected)
size_t pullAtMost(void *buf, size_t len)
Definition: Cursor.h:407
void runBenchmarks()
Definition: Benchmark.cpp:456
bool prefix(Cursor &c, uint32_t expected)
BENCHMARK_RELATIVE(prefix, iters)
char ** argv
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
size_t read(T &out, folly::io::Cursor &cursor)
Definition: Types-inl.h:258
unique_ptr< IOBuf > iobuf_read_benchmark
void prependChain(std::unique_ptr< IOBuf > &&iobuf)
Definition: IOBuf.cpp:509
BENCHMARK(fbFollyGlobalBenchmarkBaseline)
Definition: Benchmark.cpp:84
int main(int argc, char **argv)
Range< const unsigned char * > ByteRange
Definition: Range.h:1163
DECLARE_bool(benchmark)
Formatter< false, Args... > format(StringPiece fmt, Args &&...args)
Definition: Format.h:271
Range< const char * > StringPiece
void runBenchmark()
char c
void benchmark(size_t n)
void append(std::size_t amount)
Definition: IOBuf.h:689
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258
unique_ptr< IOBuf > iobuf_benchmark