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.
22 #include <glog/logging.h>
24 #include <folly/gen/Base.h>
25 #include <folly/gen/Parallel.h>
26 #include <folly/gen/test/Bench.h>
30 std::max(1, (int32_t) sysconf(_SC_NPROCESSORS_CONF) / 2),
33 using namespace folly::gen;
37 constexpr int kFib = 28; // unit of work
38 size_t fib(int n) { return n <= 1 ? 1 : fib(n - 1) + fib(n - 2); }
40 static auto isPrimeSlow = [](int n) {
44 for (int d = 3; d * d <= n; d += 2) {
54 seq(1, 1 << 20) | filter(isPrimeSlow) | as<vector>();
56 static auto isPrime = [](int n) {
58 | until([&](int d) { return d * d > n; })
59 | filter([&](int d) { return 0 == n % d; })
63 static auto factors = [](int n) {
65 | until([&](int d) { return d * d > n; })
66 | filter([&](int d) { return 0 == n % d; })
70 static auto factorsSlow = [](int n) {
72 | filter([&](int d) { return 0 == n % d; })
76 static auto sleepyWork = [](int i) {
77 const auto sleepyTime = std::chrono::microseconds(100);
78 std::this_thread::sleep_for(sleepyTime);
82 static auto sleepAndWork = [](int i) {
83 return factorsSlow(i) + sleepyWork(i);
87 auto v = seq(start) | take(1 << 20) | as<vector>();
88 auto small = from(v) | take(1 << 12);
89 auto medium = from(v) | take(1 << 14);
90 auto large = from(v) | take(1 << 18);
92 auto chunks = chunked(v);
94 BENCH_GEN(small | map(factorsSlow) | sum);
95 BENCH_GEN_REL(small | parallel(map(factorsSlow)) | sum);
96 BENCHMARK_DRAW_LINE();
98 BENCH_GEN(small | map(factors) | sum);
99 BENCH_GEN_REL(small | parallel(map(factors)) | sum);
100 BENCHMARK_DRAW_LINE();
102 BENCH_GEN(large | map(factors) | sum);
103 BENCH_GEN_REL(large | parallel(map(factors)) | sum);
104 BENCHMARK_DRAW_LINE();
108 BENCH_GEN(huge | filter(isPrime) | count);
109 BENCH_GEN_REL(ch | cat | filter(isPrime) | count);
110 BENCH_GEN_REL(ch | parallel(cat | filter(isPrime)) | count);
111 BENCH_GEN_REL(ch | parallel(cat | filter(isPrime) | sub(count)) | sum);
112 BENCHMARK_DRAW_LINE();
114 BENCH_GEN(small | map(sleepAndWork) | sum);
115 BENCH_GEN_REL(small | parallel(map(sleepAndWork)) | sum);
116 BENCHMARK_DRAW_LINE();
118 const int fibs = 1000;
119 BENCH_GEN(seq(1, fibs) | map([](int) { return fib(kFib); }) | sum);
120 BENCH_GEN_REL(seq(1, fibs) |
121 parallel(map([](int) { return fib(kFib); }) | sub(sum)) | sum);
123 auto threads = seq(1, int(FLAGS_threads))
125 return std::thread([=] {
126 return range((i + 0) * fibs / FLAGS_threads,
127 (i + 1) * fibs / FLAGS_threads) |
128 map([](int) { return fib(kFib); }) | sum;
132 from(threads) | [](std::thread &thread) { thread.join(); };
135 BENCHMARK_DRAW_LINE();
138 ============================================================================
139 folly/gen/test/ParallelBenchmark.cpp relative time/iter iters/s
140 ============================================================================
141 small | map(factorsSlow) | sum 4.59s 217.87m
142 small | parallel(map(factorsSlow)) | sum 1588.86% 288.88ms 3.46
143 ----------------------------------------------------------------------------
144 small | map(factors) | sum 9.62ms 103.94
145 small | parallel(map(factors)) | sum 89.15% 10.79ms 92.66
146 ----------------------------------------------------------------------------
147 large | map(factors) | sum 650.52ms 1.54
148 large | parallel(map(factors)) | sum 53.82% 1.21s 827.41m
149 ----------------------------------------------------------------------------
150 huge | filter(isPrime) | count 295.93ms 3.38
151 ch | cat | filter(isPrime) | count 99.76% 296.64ms 3.37
152 ch | parallel(cat | filter(isPrime)) | count 142.75% 207.31ms 4.82
153 ch | parallel(cat | filter(isPrime) | sub(count 1538.50% 19.24ms 51.99
154 ----------------------------------------------------------------------------
155 small | map(sleepAndWork) | sum 5.37s 186.18m
156 small | parallel(map(sleepAndWork)) | sum 1840.38% 291.85ms 3.43
157 ----------------------------------------------------------------------------
158 seq(1, fibs) | map([](int) { return fib(kFib); 1.49s 669.53m
159 seq(1, fibs) | parallel(map([](int) { return fi 1698.07% 87.96ms 11.37
160 [] { auto threads = seq(1, int(FLAGS_threads)) 1571.16% 95.06ms 10.52
161 ----------------------------------------------------------------------------
162 ============================================================================
164 int main(int argc, char *argv[]) {
165 gflags::ParseCommandLineFlags(&argc, &argv, true);
166 folly::runBenchmarks();