Fix SimpleBarrier
[folly.git] / folly / test / ForeachBenchmark.cpp
1 /*
2  * Copyright 2016 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 <folly/Foreach.h>
18
19 #include <folly/Benchmark.h>
20 #include <folly/portability/GTest.h>
21
22 #include <map>
23
24 using namespace folly;
25 using namespace folly::detail;
26
27 // Benchmarks:
28 // 1. Benchmark iterating through the man with FOR_EACH, and also assign
29 //    iter->first and iter->second to local vars inside the FOR_EACH loop.
30 // 2. Benchmark iterating through the man with FOR_EACH, but use iter->first and
31 //    iter->second as is, without assigning to local variables.
32 // 3. Use FOR_EACH_KV loop to iterate through the map.
33
34 std::map<int, std::string> bmMap; // For use in benchmarks below.
35
36 void setupBenchmark(size_t iters) {
37   bmMap.clear();
38   for (size_t i = 0; i < iters; ++i) {
39     bmMap[i] = "teststring";
40   }
41 }
42
43 BENCHMARK(ForEachKVNoMacroAssign, iters) {
44   int sumKeys = 0;
45   std::string sumValues;
46
47   BENCHMARK_SUSPEND { setupBenchmark(iters); }
48
49   FOR_EACH(iter, bmMap) {
50     const int k = iter->first;
51     const std::string v = iter->second;
52     sumKeys += k;
53     sumValues += v;
54   }
55 }
56
57 BENCHMARK(ForEachKVNoMacroNoAssign, iters) {
58   int sumKeys = 0;
59   std::string sumValues;
60
61   BENCHMARK_SUSPEND { setupBenchmark(iters); }
62
63   FOR_EACH(iter, bmMap) {
64     sumKeys += iter->first;
65     sumValues += iter->second;
66   }
67 }
68
69 BENCHMARK(ManualLoopNoAssign, iters) {
70   int sumKeys = 0;
71   std::string sumValues;
72
73   BENCHMARK_SUSPEND { setupBenchmark(iters); }
74
75   for (auto iter = bmMap.begin(); iter != bmMap.end(); ++iter) {
76     sumKeys += iter->first;
77     sumValues += iter->second;
78   }
79 }
80
81 BENCHMARK(ForEachKVMacro, iters) {
82   int sumKeys = 0;
83   std::string sumValues;
84
85   BENCHMARK_SUSPEND { setupBenchmark(iters); }
86
87   FOR_EACH_KV(k, v, bmMap) {
88     sumKeys += k;
89     sumValues += v;
90   }
91 }
92
93 BENCHMARK(ForEachManual, iters) {
94   int sum = 1;
95   for (size_t i = 1; i < iters; ++i) {
96     sum *= i;
97   }
98   doNotOptimizeAway(sum);
99 }
100
101 BENCHMARK(ForEachRange, iters) {
102   int sum = 1;
103   FOR_EACH_RANGE(i, 1, iters) { sum *= i; }
104   doNotOptimizeAway(sum);
105 }
106
107 BENCHMARK(ForEachDescendingManual, iters) {
108   int sum = 1;
109   for (size_t i = iters; i-- > 1;) {
110     sum *= i;
111   }
112   doNotOptimizeAway(sum);
113 }
114
115 BENCHMARK(ForEachRangeR, iters) {
116   int sum = 1;
117   FOR_EACH_RANGE_R(i, 1U, iters) { sum *= i; }
118   doNotOptimizeAway(sum);
119 }
120
121 int main(int argc, char** argv) {
122   testing::InitGoogleTest(&argc, argv);
123   gflags::ParseCommandLineFlags(&argc, &argv, true);
124   auto r = RUN_ALL_TESTS();
125   if (r) {
126     return r;
127   }
128   runBenchmarks();
129   return 0;
130 }