2 * Copyright (c) Meta Platforms, Inc. and affiliates.
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
;
28 static std::atomic
<int> testSize(1000);
30 static vector
<int> testVector
=
31 seq(1, testSize
.load())
32 | mapped([](int) { return rand(); })
35 static vector
<vector
<int>> testVectorVector
=
38 return seq(1, i
) | as
<vector
>();
41 static vector
<fbstring
> strings
=
47 auto square
= [](int x
) { return x
* x
; };
49 BENCHMARK(Sum_Basic_NoGen
, iters
) {
50 int limit
= testSize
.load();
53 for (int i
= 0; i
< limit
; ++i
) {
57 folly::doNotOptimizeAway(s
);
60 BENCHMARK_RELATIVE(Sum_Basic_Gen
, iters
) {
61 int limit
= testSize
.load();
64 s
+= range(0, limit
) | sum
;
66 folly::doNotOptimizeAway(s
);
69 BENCHMARK_DRAW_LINE();
71 BENCHMARK(Sum_Vector_NoGen
, iters
) {
74 for (auto& i
: testVector
) {
78 folly::doNotOptimizeAway(s
);
81 BENCHMARK_RELATIVE(Sum_Vector_Gen
, iters
) {
84 s
+= from(testVector
) | sum
;
86 folly::doNotOptimizeAway(s
);
89 BENCHMARK_DRAW_LINE();
91 BENCHMARK(Member
, iters
) {
96 | member(&fbstring::size
)
100 folly::doNotOptimizeAway(s
);
103 BENCHMARK_RELATIVE(MapMember
, iters
) {
108 | map([](const fbstring
& x
) { return x
.size(); })
112 folly::doNotOptimizeAway(s
);
115 BENCHMARK_DRAW_LINE();
117 BENCHMARK(Count_Vector_NoGen
, iters
) {
120 for (auto& i
: testVector
) {
121 if (i
* 2 < rand()) {
126 folly::doNotOptimizeAway(s
);
129 BENCHMARK_RELATIVE(Count_Vector_Gen
, iters
) {
133 s
+= from(testVector
)
135 return i
* 2 < rand();
140 folly::doNotOptimizeAway(s
);
143 BENCHMARK_DRAW_LINE();
145 BENCHMARK(Fib_Sum_NoGen
, iters
) {
148 auto fib
= [](size_t limit
) -> vector
<int> {
152 for (size_t i
= 0; i
< limit
; i
+= 2) {
153 ret
.push_back(a
+= b
);
154 ret
.push_back(b
+= a
);
158 for (auto& v
: fib(testSize
.load())) {
162 folly::doNotOptimizeAway(s
);
165 BENCHMARK_RELATIVE(Fib_Sum_Gen
, iters
) {
168 auto fib
= GENERATOR(int) {
176 // Early stopping implemented with exceptions.
177 s
+= fib
| take(testSize
.load()) | sum
;
179 folly::doNotOptimizeAway(s
);
182 BENCHMARK_RELATIVE(Fib_Sum_Gen_Limit
, iters
) {
185 size_t limit
= testSize
.load();
186 auto fib
= GENERATOR(int) {
189 for (size_t i
= 0; i
< limit
; i
+= 2) {
194 // No early stopping.
197 folly::doNotOptimizeAway(s
);
201 template <class Yield
>
202 void operator()(Yield
&& yield
) const {
212 BENCHMARK_RELATIVE(Fib_Sum_Gen_Static
, iters
) {
215 auto fib
= generator
<int>(FibYielder());
216 s
+= fib
| take(testSize
.load()) | sum
;
218 folly::doNotOptimizeAway(s
);
221 BENCHMARK_DRAW_LINE();
223 BENCHMARK(VirtualGen_0Virtual
, iters
) {
226 auto numbers
= seq(1, 10000);
227 auto squares
= numbers
| map(square
);
228 auto quads
= squares
| map(square
);
231 folly::doNotOptimizeAway(s
);
234 BENCHMARK_RELATIVE(VirtualGen_1Virtual
, iters
) {
237 VirtualGen
<int> numbers
= seq(1, 10000);
238 auto squares
= numbers
| map(square
);
239 auto quads
= squares
| map(square
);
242 folly::doNotOptimizeAway(s
);
245 BENCHMARK_RELATIVE(VirtualGen_2Virtual
, iters
) {
248 VirtualGen
<int> numbers
= seq(1, 10000);
249 VirtualGen
<int> squares
= numbers
| map(square
);
250 auto quads
= squares
| map(square
);
253 folly::doNotOptimizeAway(s
);
256 BENCHMARK_RELATIVE(VirtualGen_3Virtual
, iters
) {
259 VirtualGen
<int> numbers
= seq(1, 10000);
260 VirtualGen
<int> squares
= numbers
| map(square
);
261 VirtualGen
<int> quads
= squares
| map(square
);
264 folly::doNotOptimizeAway(s
);
267 BENCHMARK_DRAW_LINE();
269 BENCHMARK(Concat_NoGen
, iters
) {
272 for (auto& v
: testVectorVector
) {
278 folly::doNotOptimizeAway(s
);
281 BENCHMARK_RELATIVE(Concat_Gen
, iters
) {
284 s
+= from(testVectorVector
) | rconcat
| sum
;
286 folly::doNotOptimizeAway(s
);
289 BENCHMARK_DRAW_LINE();
291 BENCHMARK(Composed_NoGen
, iters
) {
294 for (auto& i
: testVector
) {
298 folly::doNotOptimizeAway(s
);
301 BENCHMARK_RELATIVE(Composed_Gen
, iters
) {
303 auto sumSq
= map(square
) | sum
;
305 s
+= from(testVector
) | sumSq
;
307 folly::doNotOptimizeAway(s
);
310 BENCHMARK_RELATIVE(Composed_GenRegular
, iters
) {
313 s
+= from(testVector
) | map(square
) | sum
;
315 folly::doNotOptimizeAway(s
);
318 BENCHMARK_DRAW_LINE();
320 BENCHMARK(Sample
, iters
) {
323 auto sampler
= seq(1, 10 * 1000 * 1000) | sample(1000);
324 s
+= (sampler
| sum
);
326 folly::doNotOptimizeAway(s
);
329 // Results from an Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz
330 // ============================================================================
331 // folly/gen/test/BaseBenchmark.cpp relative time/iter iters/s
332 // ============================================================================
333 // Sum_Basic_NoGen 372.39ns 2.69M
334 // Sum_Basic_Gen 195.96% 190.03ns 5.26M
335 // ----------------------------------------------------------------------------
336 // Sum_Vector_NoGen 200.41ns 4.99M
337 // Sum_Vector_Gen 77.14% 259.81ns 3.85M
338 // ----------------------------------------------------------------------------
339 // Member 4.56us 219.42K
340 // MapMember 400.47% 1.14us 878.73K
341 // ----------------------------------------------------------------------------
342 // Count_Vector_NoGen 13.96us 71.64K
343 // Count_Vector_Gen 86.05% 16.22us 61.65K
344 // ----------------------------------------------------------------------------
345 // Fib_Sum_NoGen 2.21us 452.63K
346 // Fib_Sum_Gen 23.94% 9.23us 108.36K
347 // Fib_Sum_Gen_Static 48.77% 4.53us 220.73K
348 // ----------------------------------------------------------------------------
349 // VirtualGen_0Virtual 9.60us 104.13K
350 // VirtualGen_1Virtual 28.00% 34.30us 29.15K
351 // VirtualGen_2Virtual 22.62% 42.46us 23.55K
352 // VirtualGen_3Virtual 16.96% 56.64us 17.66K
353 // ----------------------------------------------------------------------------
354 // Concat_NoGen 2.20us 453.66K
355 // Concat_Gen 109.49% 2.01us 496.70K
356 // ----------------------------------------------------------------------------
357 // Composed_NoGen 545.32ns 1.83M
358 // Composed_Gen 87.94% 620.07ns 1.61M
359 // Composed_GenRegular 88.13% 618.74ns 1.62M
360 // ----------------------------------------------------------------------------
361 // Sample 176.48ms 5.67
362 // ============================================================================
364 int main(int argc
, char* argv
[]) {
365 gflags::ParseCommandLineFlags(&argc
, &argv
, true);
366 folly::runBenchmarks();