2 * Copyright 2016 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.
17 #include <folly/Foreach.h>
19 #include <folly/Benchmark.h>
20 #include <folly/portability/GTest.h>
24 using namespace folly;
25 using namespace folly::detail;
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.
34 std::map<int, std::string> bmMap; // For use in benchmarks below.
36 void setupBenchmark(size_t iters) {
38 for (size_t i = 0; i < iters; ++i) {
39 bmMap[i] = "teststring";
43 BENCHMARK(ForEachKVNoMacroAssign, iters) {
45 std::string sumValues;
47 BENCHMARK_SUSPEND { setupBenchmark(iters); }
49 FOR_EACH(iter, bmMap) {
50 const int k = iter->first;
51 const std::string v = iter->second;
57 BENCHMARK(ForEachKVNoMacroNoAssign, iters) {
59 std::string sumValues;
61 BENCHMARK_SUSPEND { setupBenchmark(iters); }
63 FOR_EACH(iter, bmMap) {
64 sumKeys += iter->first;
65 sumValues += iter->second;
69 BENCHMARK(ManualLoopNoAssign, iters) {
71 std::string sumValues;
73 BENCHMARK_SUSPEND { setupBenchmark(iters); }
75 for (auto iter = bmMap.begin(); iter != bmMap.end(); ++iter) {
76 sumKeys += iter->first;
77 sumValues += iter->second;
81 BENCHMARK(ForEachKVMacro, iters) {
83 std::string sumValues;
85 BENCHMARK_SUSPEND { setupBenchmark(iters); }
87 FOR_EACH_KV(k, v, bmMap) {
93 BENCHMARK(ForEachManual, iters) {
95 for (size_t i = 1; i < iters; ++i) {
98 doNotOptimizeAway(sum);
101 BENCHMARK(ForEachRange, iters) {
103 FOR_EACH_RANGE(i, 1, iters) { sum *= i; }
104 doNotOptimizeAway(sum);
107 BENCHMARK(ForEachDescendingManual, iters) {
109 for (size_t i = iters; i-- > 1;) {
112 doNotOptimizeAway(sum);
115 BENCHMARK(ForEachRangeR, iters) {
117 FOR_EACH_RANGE_R(i, 1U, iters) { sum *= i; }
118 doNotOptimizeAway(sum);
121 int main(int argc, char** argv) {
122 testing::InitGoogleTest(&argc, argv);
123 gflags::ParseCommandLineFlags(&argc, &argv, true);
124 auto r = RUN_ALL_TESTS();