2 * Copyright 2014-present Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <glog/logging.h>
21 #include <folly/Benchmark.h>
22 #include <folly/gen/Base.h>
24 using namespace folly::gen;
25 using folly::fbstring;
31 static std::atomic<int> testSize(1000);
32 static vector<int> testVector =
33 seq(1, testSize.load())
34 | mapped([](int) { return rand(); })
37 static vector<vector<int>> testVectorVector =
40 return seq(1, i) | as<vector>();
43 static vector<fbstring> strings =
48 auto square = [](int x) { return x * x; };
50 BENCHMARK(Sum_Basic_NoGen, iters) {
51 int limit = testSize.load();
54 for (int i = 0; i < limit; ++i) {
58 folly::doNotOptimizeAway(s);
61 BENCHMARK_RELATIVE(Sum_Basic_Gen, iters) {
62 int limit = testSize.load();
65 s += range(0, limit) | sum;
67 folly::doNotOptimizeAway(s);
72 BENCHMARK(Sum_Vector_NoGen, iters) {
75 for (auto& i : testVector) {
79 folly::doNotOptimizeAway(s);
82 BENCHMARK_RELATIVE(Sum_Vector_Gen, iters) {
85 s += from(testVector) | sum;
87 folly::doNotOptimizeAway(s);
92 BENCHMARK(Member, iters) {
96 | member(&fbstring::size)
99 folly::doNotOptimizeAway(s);
102 BENCHMARK_RELATIVE(MapMember, iters) {
106 | map([](const fbstring& x) { return x.size(); })
109 folly::doNotOptimizeAway(s);
112 BENCHMARK_DRAW_LINE()
114 BENCHMARK(Count_Vector_NoGen, iters) {
117 for (auto& i : testVector) {
118 if (i * 2 < rand()) {
123 folly::doNotOptimizeAway(s);
126 BENCHMARK_RELATIVE(Count_Vector_Gen, iters) {
129 s += from(testVector)
131 return i * 2 < rand();
135 folly::doNotOptimizeAway(s);
138 BENCHMARK_DRAW_LINE()
140 BENCHMARK(Fib_Sum_NoGen, iters) {
143 auto fib = [](size_t limit) -> vector<int> {
147 for (size_t i = 0; i < limit; i += 2) {
148 ret.push_back(a += b);
149 ret.push_back(b += a);
153 for (auto& v : fib(testSize.load())) {
157 folly::doNotOptimizeAway(s);
160 BENCHMARK_RELATIVE(Fib_Sum_Gen, iters) {
163 auto fib = GENERATOR(int) {
171 // Early stopping implemented with exceptions.
172 s += fib | take(testSize.load()) | sum;
174 folly::doNotOptimizeAway(s);
177 BENCHMARK_RELATIVE(Fib_Sum_Gen_Limit, iters) {
180 size_t limit = testSize.load();
181 auto fib = GENERATOR(int) {
184 for (size_t i = 0; i < limit; i += 2) {
189 // No early stopping.
192 folly::doNotOptimizeAway(s);
196 template <class Yield>
197 void operator()(Yield&& yield) const {
207 BENCHMARK_RELATIVE(Fib_Sum_Gen_Static, iters) {
210 auto fib = generator<int>(FibYielder());
211 s += fib | take(testSize.load()) | sum;
213 folly::doNotOptimizeAway(s);
216 BENCHMARK_DRAW_LINE()
218 BENCHMARK(VirtualGen_0Virtual, iters) {
221 auto numbers = seq(1, 10000);
222 auto squares = numbers | map(square);
223 auto quads = squares | map(square);
226 folly::doNotOptimizeAway(s);
229 BENCHMARK_RELATIVE(VirtualGen_1Virtual, iters) {
232 VirtualGen<int> numbers = seq(1, 10000);
233 auto squares = numbers | map(square);
234 auto quads = squares | map(square);
237 folly::doNotOptimizeAway(s);
240 BENCHMARK_RELATIVE(VirtualGen_2Virtual, iters) {
243 VirtualGen<int> numbers = seq(1, 10000);
244 VirtualGen<int> squares = numbers | map(square);
245 auto quads = squares | map(square);
248 folly::doNotOptimizeAway(s);
251 BENCHMARK_RELATIVE(VirtualGen_3Virtual, iters) {
254 VirtualGen<int> numbers = seq(1, 10000);
255 VirtualGen<int> squares = numbers | map(square);
256 VirtualGen<int> quads = squares | map(square);
259 folly::doNotOptimizeAway(s);
262 BENCHMARK_DRAW_LINE()
264 BENCHMARK(Concat_NoGen, iters) {
267 for (auto& v : testVectorVector) {
273 folly::doNotOptimizeAway(s);
276 BENCHMARK_RELATIVE(Concat_Gen, iters) {
279 s += from(testVectorVector) | rconcat | sum;
281 folly::doNotOptimizeAway(s);
284 BENCHMARK_DRAW_LINE()
286 BENCHMARK(Composed_NoGen, iters) {
289 for (auto& i : testVector) {
293 folly::doNotOptimizeAway(s);
296 BENCHMARK_RELATIVE(Composed_Gen, iters) {
298 auto sumSq = map(square) | sum;
300 s += from(testVector) | sumSq;
302 folly::doNotOptimizeAway(s);
305 BENCHMARK_RELATIVE(Composed_GenRegular, iters) {
308 s += from(testVector) | map(square) | sum;
310 folly::doNotOptimizeAway(s);
313 BENCHMARK_DRAW_LINE()
315 BENCHMARK(Sample, iters) {
318 auto sampler = seq(1, 10 * 1000 * 1000) | sample(1000);
319 s += (sampler | sum);
321 folly::doNotOptimizeAway(s);
324 // Results from an Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz
325 // ============================================================================
326 // folly/gen/test/BaseBenchmark.cpp relative time/iter iters/s
327 // ============================================================================
328 // Sum_Basic_NoGen 372.39ns 2.69M
329 // Sum_Basic_Gen 195.96% 190.03ns 5.26M
330 // ----------------------------------------------------------------------------
331 // Sum_Vector_NoGen 200.41ns 4.99M
332 // Sum_Vector_Gen 77.14% 259.81ns 3.85M
333 // ----------------------------------------------------------------------------
334 // Member 4.56us 219.42K
335 // MapMember 400.47% 1.14us 878.73K
336 // ----------------------------------------------------------------------------
337 // Count_Vector_NoGen 13.96us 71.64K
338 // Count_Vector_Gen 86.05% 16.22us 61.65K
339 // ----------------------------------------------------------------------------
340 // Fib_Sum_NoGen 2.21us 452.63K
341 // Fib_Sum_Gen 23.94% 9.23us 108.36K
342 // Fib_Sum_Gen_Static 48.77% 4.53us 220.73K
343 // ----------------------------------------------------------------------------
344 // VirtualGen_0Virtual 9.60us 104.13K
345 // VirtualGen_1Virtual 28.00% 34.30us 29.15K
346 // VirtualGen_2Virtual 22.62% 42.46us 23.55K
347 // VirtualGen_3Virtual 16.96% 56.64us 17.66K
348 // ----------------------------------------------------------------------------
349 // Concat_NoGen 2.20us 453.66K
350 // Concat_Gen 109.49% 2.01us 496.70K
351 // ----------------------------------------------------------------------------
352 // Composed_NoGen 545.32ns 1.83M
353 // Composed_Gen 87.94% 620.07ns 1.61M
354 // Composed_GenRegular 88.13% 618.74ns 1.62M
355 // ----------------------------------------------------------------------------
356 // Sample 176.48ms 5.67
357 // ============================================================================
359 int main(int argc, char *argv[]) {
360 gflags::ParseCommandLineFlags(&argc, &argv, true);
361 folly::runBenchmarks();