proxygen
BaseBenchmark.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2014-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 <atomic>
18 
19 #include <glog/logging.h>
20 
21 #include <folly/Benchmark.h>
22 #include <folly/gen/Base.h>
23 
24 using namespace folly::gen;
25 using folly::fbstring;
26 using std::pair;
27 using std::set;
28 using std::tuple;
29 using std::vector;
30 
31 static std::atomic<int> testSize(1000);
32 // clang-format off
33 static vector<int> testVector =
34  seq(1, testSize.load())
35  | mapped([](int) { return rand(); })
36  | as<vector>();
37 
38 static vector<vector<int>> testVectorVector =
39  seq(1, 100)
40  | map([](int i) {
41  return seq(1, i) | as<vector>();
42  })
43  | as<vector>();
44 static vector<fbstring> strings =
45  from(testVector)
46  | eachTo<fbstring>()
47  | as<vector>();
48 // clang-format on
49 
50 auto square = [](int x) { return x * x; };
51 
52 BENCHMARK(Sum_Basic_NoGen, iters) {
53  int limit = testSize.load();
54  int s = 0;
55  while (iters--) {
56  for (int i = 0; i < limit; ++i) {
57  s += i;
58  }
59  }
61 }
62 
63 BENCHMARK_RELATIVE(Sum_Basic_Gen, iters) {
64  int limit = testSize.load();
65  int s = 0;
66  while (iters--) {
67  s += range(0, limit) | sum;
68  }
70 }
71 
73 
74 BENCHMARK(Sum_Vector_NoGen, iters) {
75  int s = 0;
76  while (iters--) {
77  for (auto& i : testVector) {
78  s += i;
79  }
80  }
82 }
83 
84 BENCHMARK_RELATIVE(Sum_Vector_Gen, iters) {
85  int s = 0;
86  while (iters--) {
87  s += from(testVector) | sum;
88  }
90 }
91 
93 
94 BENCHMARK(Member, iters) {
95  int s = 0;
96  while (iters--) {
97  // clang-format off
98  s += from(strings)
100  | sum;
101  // clang-format on
102  }
104 }
105 
106 BENCHMARK_RELATIVE(MapMember, iters) {
107  int s = 0;
108  while (iters--) {
109  // clang-format off
110  s += from(strings)
111  | map([](const fbstring& x) { return x.size(); })
112  | sum;
113  // clang-format on
114  }
116 }
117 
119 
120 BENCHMARK(Count_Vector_NoGen, iters) {
121  int s = 0;
122  while (iters--) {
123  for (auto& i : testVector) {
124  if (i * 2 < rand()) {
125  ++s;
126  }
127  }
128  }
130 }
131 
132 BENCHMARK_RELATIVE(Count_Vector_Gen, iters) {
133  int s = 0;
134  while (iters--) {
135  // clang-format off
136  s += from(testVector)
137  | filter([](int i) {
138  return i * 2 < rand();
139  })
140  | count;
141  // clang-format on
142  }
144 }
145 
147 
148 BENCHMARK(Fib_Sum_NoGen, iters) {
149  int s = 0;
150  while (iters--) {
151  auto fib = [](size_t limit) -> vector<int> {
152  vector<int> ret;
153  int a = 0;
154  int b = 1;
155  for (size_t i = 0; i < limit; i += 2) {
156  ret.push_back(a += b);
157  ret.push_back(b += a);
158  }
159  return ret;
160  };
161  for (auto& v : fib(testSize.load())) {
162  s += v;
163  }
164  }
166 }
167 
168 BENCHMARK_RELATIVE(Fib_Sum_Gen, iters) {
169  int s = 0;
170  while (iters--) {
171  auto fib = GENERATOR(int) {
172  int a = 0;
173  int b = 1;
174  for (;;) {
175  yield(a += b);
176  yield(b += a);
177  }
178  };
179  // Early stopping implemented with exceptions.
180  s += fib | take(testSize.load()) | sum;
181  }
183 }
184 
185 BENCHMARK_RELATIVE(Fib_Sum_Gen_Limit, iters) {
186  int s = 0;
187  while (iters--) {
188  size_t limit = testSize.load();
189  auto fib = GENERATOR(int) {
190  int a = 0;
191  int b = 1;
192  for (size_t i = 0; i < limit; i += 2) {
193  yield(a += b);
194  yield(b += a);
195  }
196  };
197  // No early stopping.
198  s += fib | sum;
199  }
201 }
202 
203 struct FibYielder {
204  template <class Yield>
205  void operator()(Yield&& yield) const {
206  int a = 0;
207  int b = 1;
208  for (;;) {
209  yield(a += b);
210  yield(b += a);
211  }
212  }
213 };
214 
215 BENCHMARK_RELATIVE(Fib_Sum_Gen_Static, iters) {
216  int s = 0;
217  while (iters--) {
218  auto fib = generator<int>(FibYielder());
219  s += fib | take(testSize.load()) | sum;
220  }
222 }
223 
225 
226 BENCHMARK(VirtualGen_0Virtual, iters) {
227  int s = 0;
228  while (iters--) {
229  auto numbers = seq(1, 10000);
230  auto squares = numbers | map(square);
231  auto quads = squares | map(square);
232  s += quads | sum;
233  }
235 }
236 
237 BENCHMARK_RELATIVE(VirtualGen_1Virtual, iters) {
238  int s = 0;
239  while (iters--) {
240  VirtualGen<int> numbers = seq(1, 10000);
241  auto squares = numbers | map(square);
242  auto quads = squares | map(square);
243  s += quads | sum;
244  }
246 }
247 
248 BENCHMARK_RELATIVE(VirtualGen_2Virtual, iters) {
249  int s = 0;
250  while (iters--) {
251  VirtualGen<int> numbers = seq(1, 10000);
252  VirtualGen<int> squares = numbers | map(square);
253  auto quads = squares | map(square);
254  s += quads | sum;
255  }
257 }
258 
259 BENCHMARK_RELATIVE(VirtualGen_3Virtual, iters) {
260  int s = 0;
261  while (iters--) {
262  VirtualGen<int> numbers = seq(1, 10000);
263  VirtualGen<int> squares = numbers | map(square);
264  VirtualGen<int> quads = squares | map(square);
265  s += quads | sum;
266  }
268 }
269 
271 
272 BENCHMARK(Concat_NoGen, iters) {
273  int s = 0;
274  while (iters--) {
275  for (auto& v : testVectorVector) {
276  for (auto& i : v) {
277  s += i;
278  }
279  }
280  }
282 }
283 
284 BENCHMARK_RELATIVE(Concat_Gen, iters) {
285  int s = 0;
286  while (iters--) {
287  s += from(testVectorVector) | rconcat | sum;
288  }
290 }
291 
293 
294 BENCHMARK(Composed_NoGen, iters) {
295  int s = 0;
296  while (iters--) {
297  for (auto& i : testVector) {
298  s += i * i;
299  }
300  }
302 }
303 
304 BENCHMARK_RELATIVE(Composed_Gen, iters) {
305  int s = 0;
306  auto sumSq = map(square) | sum;
307  while (iters--) {
308  s += from(testVector) | sumSq;
309  }
311 }
312 
313 BENCHMARK_RELATIVE(Composed_GenRegular, iters) {
314  int s = 0;
315  while (iters--) {
316  s += from(testVector) | map(square) | sum;
317  }
319 }
320 
322 
323 BENCHMARK(Sample, iters) {
324  size_t s = 0;
325  while (iters--) {
326  auto sampler = seq(1, 10 * 1000 * 1000) | sample(1000);
327  s += (sampler | sum);
328  }
330 }
331 
332 // Results from an Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz
333 // ============================================================================
334 // folly/gen/test/BaseBenchmark.cpp relative time/iter iters/s
335 // ============================================================================
336 // Sum_Basic_NoGen 372.39ns 2.69M
337 // Sum_Basic_Gen 195.96% 190.03ns 5.26M
338 // ----------------------------------------------------------------------------
339 // Sum_Vector_NoGen 200.41ns 4.99M
340 // Sum_Vector_Gen 77.14% 259.81ns 3.85M
341 // ----------------------------------------------------------------------------
342 // Member 4.56us 219.42K
343 // MapMember 400.47% 1.14us 878.73K
344 // ----------------------------------------------------------------------------
345 // Count_Vector_NoGen 13.96us 71.64K
346 // Count_Vector_Gen 86.05% 16.22us 61.65K
347 // ----------------------------------------------------------------------------
348 // Fib_Sum_NoGen 2.21us 452.63K
349 // Fib_Sum_Gen 23.94% 9.23us 108.36K
350 // Fib_Sum_Gen_Static 48.77% 4.53us 220.73K
351 // ----------------------------------------------------------------------------
352 // VirtualGen_0Virtual 9.60us 104.13K
353 // VirtualGen_1Virtual 28.00% 34.30us 29.15K
354 // VirtualGen_2Virtual 22.62% 42.46us 23.55K
355 // VirtualGen_3Virtual 16.96% 56.64us 17.66K
356 // ----------------------------------------------------------------------------
357 // Concat_NoGen 2.20us 453.66K
358 // Concat_Gen 109.49% 2.01us 496.70K
359 // ----------------------------------------------------------------------------
360 // Composed_NoGen 545.32ns 1.83M
361 // Composed_Gen 87.94% 620.07ns 1.61M
362 // Composed_GenRegular 88.13% 618.74ns 1.62M
363 // ----------------------------------------------------------------------------
364 // Sample 176.48ms 5.67
365 // ============================================================================
366 
367 int main(int argc, char* argv[]) {
368  gflags::ParseCommandLineFlags(&argc, &argv, true);
370  return 0;
371 }
Definition: InvokeTest.cpp:58
size_type size() const
Definition: FBString.h:1337
auto v
BENCHMARK_RELATIVE(Sum_Basic_Gen, iters)
char b
constexpr detail::Count count
Definition: Base-inl.h:2551
static std::atomic< int > testSize(1000)
From from(Container &source)
Definition: Base.h:438
const int x
static vector< vector< int > > testVectorVector
Gen seq(Value first, Value last)
Definition: Base.h:484
void runBenchmarks()
Definition: Benchmark.cpp:456
detail::Sample< Random > sample(size_t count, Random rng=Random())
Definition: Base-inl.h:2594
constexpr detail::Sum sum
Definition: Base-inl.h:2549
#define GENERATOR(TYPE)
Definition: Base.h:515
Gen range(Value begin, Value end)
Definition: Base.h:467
char ** argv
constexpr detail::RangeConcat rconcat
Definition: Base-inl.h:2571
Map map(Predicate pred=Predicate())
Definition: Base.h:545
char a
size_t fib(int n)
Filter filter(Predicate pred=Predicate())
Definition: Base.h:646
int main(int argc, char *argv[])
std::enable_if< ExprIsConst< Constness >::value, Map >::type member(Return(Class::*member)() const)
Definition: Base.h:605
static vector< int > testVector
BENCHMARK(fbFollyGlobalBenchmarkBaseline)
Definition: Benchmark.cpp:84
BENCHMARK_DRAW_LINE()
static set< string > s
detail::Take take(Number count)
Definition: Base-inl.h:2582
Map mapped(Predicate pred=Predicate())
Definition: Base.h:540
void operator()(Yield &&yield) const
basic_fbstring< char > fbstring
Definition: FBString.h:2904
static vector< fbstring > strings
auto square
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258