2 * Copyright 2017 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; };
49 auto add = [](int a, int b) { return a + b; };
50 auto multiply = [](int a, int b) { return a * b; };
52 BENCHMARK(Sum_Basic_NoGen, iters) {
53 int limit = testSize.load();
56 for (int i = 0; i < limit; ++i) {
60 folly::doNotOptimizeAway(s);
63 BENCHMARK_RELATIVE(Sum_Basic_Gen, iters) {
64 int limit = testSize.load();
67 s += range(0, limit) | sum;
69 folly::doNotOptimizeAway(s);
74 BENCHMARK(Sum_Vector_NoGen, iters) {
77 for (auto& i : testVector) {
81 folly::doNotOptimizeAway(s);
84 BENCHMARK_RELATIVE(Sum_Vector_Gen, iters) {
87 s += from(testVector) | sum;
89 folly::doNotOptimizeAway(s);
94 BENCHMARK(Member, iters) {
98 | member(&fbstring::size)
101 folly::doNotOptimizeAway(s);
104 BENCHMARK_RELATIVE(MapMember, iters) {
108 | map([](const fbstring& x) { return x.size(); })
111 folly::doNotOptimizeAway(s);
114 BENCHMARK_DRAW_LINE()
116 BENCHMARK(Count_Vector_NoGen, iters) {
119 for (auto& i : testVector) {
120 if (i * 2 < rand()) {
125 folly::doNotOptimizeAway(s);
128 BENCHMARK_RELATIVE(Count_Vector_Gen, iters) {
131 s += from(testVector)
133 return i * 2 < rand();
137 folly::doNotOptimizeAway(s);
140 BENCHMARK_DRAW_LINE()
142 BENCHMARK(Fib_Sum_NoGen, iters) {
145 auto fib = [](int limit) -> vector<int> {
149 for (int i = 0; i * 2 < limit; ++i) {
150 ret.push_back(a += b);
151 ret.push_back(b += a);
155 for (auto& v : fib(testSize.load())) {
159 folly::doNotOptimizeAway(s);
162 BENCHMARK_RELATIVE(Fib_Sum_Gen, iters) {
165 auto fib = GENERATOR(int) {
173 s += fib | take(testSize.load()) | sum;
175 folly::doNotOptimizeAway(s);
179 template <class Yield>
180 void operator()(Yield&& yield) const {
190 BENCHMARK_RELATIVE(Fib_Sum_Gen_Static, iters) {
193 auto fib = generator<int>(FibYielder());
194 s += fib | take(testSize.load()) | sum;
196 folly::doNotOptimizeAway(s);
199 BENCHMARK_DRAW_LINE()
201 BENCHMARK(VirtualGen_0Virtual, iters) {
204 auto numbers = seq(1, 10000);
205 auto squares = numbers | map(square);
206 auto quads = squares | map(square);
209 folly::doNotOptimizeAway(s);
212 BENCHMARK_RELATIVE(VirtualGen_1Virtual, iters) {
215 VirtualGen<int> numbers = seq(1, 10000);
216 auto squares = numbers | map(square);
217 auto quads = squares | map(square);
220 folly::doNotOptimizeAway(s);
223 BENCHMARK_RELATIVE(VirtualGen_2Virtual, iters) {
226 VirtualGen<int> numbers = seq(1, 10000);
227 VirtualGen<int> squares = numbers | map(square);
228 auto quads = squares | map(square);
231 folly::doNotOptimizeAway(s);
234 BENCHMARK_RELATIVE(VirtualGen_3Virtual, iters) {
237 VirtualGen<int> numbers = seq(1, 10000);
238 VirtualGen<int> squares = numbers | map(square);
239 VirtualGen<int> quads = squares | map(square);
242 folly::doNotOptimizeAway(s);
245 BENCHMARK_DRAW_LINE()
247 BENCHMARK(Concat_NoGen, iters) {
250 for (auto& v : testVectorVector) {
256 folly::doNotOptimizeAway(s);
259 BENCHMARK_RELATIVE(Concat_Gen, iters) {
262 s += from(testVectorVector) | rconcat | sum;
264 folly::doNotOptimizeAway(s);
267 BENCHMARK_DRAW_LINE()
269 BENCHMARK(Composed_NoGen, iters) {
272 for (auto& i : testVector) {
276 folly::doNotOptimizeAway(s);
279 BENCHMARK_RELATIVE(Composed_Gen, iters) {
281 auto sumSq = map(square) | sum;
283 s += from(testVector) | sumSq;
285 folly::doNotOptimizeAway(s);
288 BENCHMARK_RELATIVE(Composed_GenRegular, iters) {
291 s += from(testVector) | map(square) | sum;
293 folly::doNotOptimizeAway(s);
296 BENCHMARK_DRAW_LINE()
298 BENCHMARK(Sample, iters) {
301 auto sampler = seq(1, 10 * 1000 * 1000) | sample(1000);
302 s += (sampler | sum);
304 folly::doNotOptimizeAway(s);
307 // Results from an Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz
308 // ============================================================================
309 // folly/gen/test/BaseBenchmark.cpp relative time/iter iters/s
310 // ============================================================================
311 // Sum_Basic_NoGen 372.39ns 2.69M
312 // Sum_Basic_Gen 195.96% 190.03ns 5.26M
313 // ----------------------------------------------------------------------------
314 // Sum_Vector_NoGen 200.41ns 4.99M
315 // Sum_Vector_Gen 77.14% 259.81ns 3.85M
316 // ----------------------------------------------------------------------------
317 // Member 4.56us 219.42K
318 // MapMember 400.47% 1.14us 878.73K
319 // ----------------------------------------------------------------------------
320 // Count_Vector_NoGen 13.96us 71.64K
321 // Count_Vector_Gen 86.05% 16.22us 61.65K
322 // ----------------------------------------------------------------------------
323 // Fib_Sum_NoGen 2.21us 452.63K
324 // Fib_Sum_Gen 23.94% 9.23us 108.36K
325 // Fib_Sum_Gen_Static 48.77% 4.53us 220.73K
326 // ----------------------------------------------------------------------------
327 // VirtualGen_0Virtual 9.60us 104.13K
328 // VirtualGen_1Virtual 28.00% 34.30us 29.15K
329 // VirtualGen_2Virtual 22.62% 42.46us 23.55K
330 // VirtualGen_3Virtual 16.96% 56.64us 17.66K
331 // ----------------------------------------------------------------------------
332 // Concat_NoGen 2.20us 453.66K
333 // Concat_Gen 109.49% 2.01us 496.70K
334 // ----------------------------------------------------------------------------
335 // Composed_NoGen 545.32ns 1.83M
336 // Composed_Gen 87.94% 620.07ns 1.61M
337 // Composed_GenRegular 88.13% 618.74ns 1.62M
338 // ----------------------------------------------------------------------------
339 // Sample 176.48ms 5.67
340 // ============================================================================
342 int main(int argc, char *argv[]) {
343 gflags::ParseCommandLineFlags(&argc, &argv, true);
344 folly::runBenchmarks();