Fix copyright lines
[folly.git] / folly / io / test / IOBufCursorBenchmark.cpp
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
24 DECLARE_bool(benchmark);
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>();
93       folly::doNotOptimizeAway(val);
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>();
104       folly::doNotOptimizeAway(val);
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
125 BENCHMARK(prefixBaseline, iters) {
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
138 BENCHMARK_RELATIVE(prefix, iters) {
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
150 /**
151  * ============================================================================
152  * folly/io/test/IOBufCursorBenchmark.cpp          relative  time/iter  iters/s
153  * ============================================================================
154  * rwPrivateCursorBenchmark                                     1.01us  985.85K
155  * rwUnshareCursorBenchmark                                     1.01us  986.70K
156  * cursorBenchmark                                              4.77us  209.61K
157  * skipBenchmark                                                4.78us  209.42K
158  * cloneBenchmark                                              26.65us   37.52K
159  * read                                                         4.35us  230.07K
160  * readSlow                                                     5.45us  183.48K
161  * prefixBaseline                                               6.44us  155.24K
162  * prefix                                           589.31%     1.09us  914.87K
163  * ============================================================================
164  */
165
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
178   folly::runBenchmarks();
179   return 0;
180 }