proxygen
FunctionRefBenchmark.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018-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 #include <folly/Benchmark.h>
17 #include <folly/Function.h>
18 #include <folly/Random.h>
19 
20 #include <cstdint>
21 #include <functional>
22 #include <memory>
23 #include <tuple>
24 #include <type_traits>
25 
54 namespace folly {
55 namespace {
56 template <typename MakeFunction>
57 void runSmallInvokeBenchmark(std::size_t iters, MakeFunction make) {
58  auto lambda = [](auto& i) {
60  return i;
61  };
62  auto func = make(lambda);
64 
65  for (auto i = std::size_t{iters}; --i;) {
67  }
68 }
69 
70 template <typename MakeFunction>
71 void runSmallCreateAndInvokeBenchmark(std::size_t iters, MakeFunction make) {
72  auto lambda = [](auto& i) {
74  return i;
75  };
76 
77  for (auto i = std::size_t{iters}; --i;) {
78  auto func = make(lambda);
81  }
82 }
83 
84 template <typename MakeFunction>
85 void runBigAndInvokeBenchmark(std::size_t iters, MakeFunction make) {
86  auto suspender = BenchmarkSuspender{};
87  auto array = std::array<std::uint8_t, 4096>{};
88 
89  auto lambda = [=](auto& i) {
90  // we use std::ignore to ensure ODR-usage of array
91  std::ignore = array;
93  return i;
94  };
95  auto func = make(lambda);
97 
98  suspender.dismissing([&] {
99  for (auto i = std::size_t{iters}; --i;) {
101  }
102  });
103 }
104 
105 template <typename MakeFunction>
106 void runBigCreateAndInvokeBenchmark(std::size_t iters, MakeFunction make) {
107  auto suspender = BenchmarkSuspender{};
108  auto array = std::array<std::uint8_t, 1024>{};
110 
111  auto lambda = [=](auto& i) {
114  return i;
115  };
116 
117  suspender.dismissing([&] {
118  for (auto i = std::size_t{iters}; --i;) {
119  auto func = make(lambda);
122  }
123  });
124 }
125 } // namespace
126 
127 BENCHMARK(SmallFunctionFunctionPointerInvoke, iters) {
128  using FPtr = size_t (*)(size_t&);
129  runSmallInvokeBenchmark(iters, [](auto& f) { return FPtr{f}; });
130 }
131 BENCHMARK(SmallFunctionStdFunctionInvoke, iters) {
132  runSmallInvokeBenchmark(
133  iters, [](auto& f) { return std::function<size_t(size_t&)>{f}; });
134 }
135 BENCHMARK(SmallFunctionStdFunctionWithReferenceWrapperInvoke, iters) {
136  runSmallInvokeBenchmark(iters, [](auto& f) {
137  return std::function<size_t(size_t&)>{std::ref(f)};
138  });
139 }
140 BENCHMARK(SmallFunctionFollyFunctionInvoke, iters) {
141  runSmallInvokeBenchmark(
142  iters, [](auto& f) { return folly::Function<size_t(size_t&)>{f}; });
143 }
144 BENCHMARK(SmallFunctionFollyFunctionRefInvoke, iters) {
145  runSmallInvokeBenchmark(
146  iters, [](auto& f) { return folly::FunctionRef<size_t(size_t&)>{f}; });
147 }
148 
150 BENCHMARK(SmallFunctionFunctionPointerCreateInvoke, iters) {
151  using FPtr = size_t (*)(size_t&);
152  runSmallCreateAndInvokeBenchmark(iters, [](auto& f) { return FPtr{f}; });
153 }
154 BENCHMARK(SmallFunctionStdFunctionCreateInvoke, iters) {
155  runSmallCreateAndInvokeBenchmark(
156  iters, [](auto& f) { return std::function<size_t(size_t&)>{f}; });
157 }
158 BENCHMARK(SmallFunctionStdFunctionReferenceWrapperCreateInvoke, iters) {
159  runSmallCreateAndInvokeBenchmark(iters, [](auto& f) {
160  return std::function<size_t(size_t&)>{std::ref(f)};
161  });
162 }
163 BENCHMARK(SmallFunctionFollyFunctionCreateInvoke, iters) {
164  runSmallCreateAndInvokeBenchmark(
165  iters, [](auto& f) { return folly::Function<size_t(size_t&)>{f}; });
166 }
167 BENCHMARK(SmallFunctionFollyFunctionRefCreateInvoke, iters) {
168  runSmallCreateAndInvokeBenchmark(
169  iters, [](auto& f) { return folly::FunctionRef<size_t(size_t&)>{f}; });
170 }
171 
173 BENCHMARK(BigFunctionStdFunctionInvoke, iters) {
174  runBigAndInvokeBenchmark(
175  iters, [](auto& f) { return std::function<size_t(size_t&)>{f}; });
176 }
177 BENCHMARK(BigFunctionStdFunctionReferenceWrapperInvoke, iters) {
178  runBigAndInvokeBenchmark(iters, [](auto& f) {
179  return std::function<size_t(size_t&)>{std::ref(f)};
180  });
181 }
182 BENCHMARK(BigFunctionFollyFunctionInvoke, iters) {
183  runBigAndInvokeBenchmark(
184  iters, [](auto& f) { return folly::Function<size_t(size_t&)>{f}; });
185 }
186 BENCHMARK(BigFunctionFollyFunctionRefInvoke, iters) {
187  runBigAndInvokeBenchmark(
188  iters, [](auto& f) { return folly::FunctionRef<size_t(size_t&)>{f}; });
189 }
190 
192 BENCHMARK(BigFunctionStdFunctionCreateInvoke, iters) {
193  runBigCreateAndInvokeBenchmark(
194  iters, [](auto& f) { return std::function<size_t(size_t&)>{f}; });
195 }
196 BENCHMARK(BigFunctionStdFunctionReferenceWrapperCreateInvoke, iters) {
197  runBigCreateAndInvokeBenchmark(iters, [](auto& f) {
198  return std::function<size_t(size_t&)>{std::ref(f)};
199  });
200 }
201 BENCHMARK(BigFunctionFollyFunctionCreateInvoke, iters) {
202  runBigCreateAndInvokeBenchmark(
203  iters, [](auto& f) { return folly::Function<size_t(size_t&)>{f}; });
204 }
205 BENCHMARK(BigFunctionFollyFunctionRefCreateInvoke, iters) {
206  runBigCreateAndInvokeBenchmark(
207  iters, [](auto& f) { return folly::FunctionRef<size_t(size_t&)>{f}; });
208 }
209 } // namespace folly
210 
211 int main(int argc, char** argv) {
212  gflags::ParseCommandLineFlags(&argc, &argv, true);
214 }
auto f
A reference wrapper for callable objects.
Definition: Function.h:893
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
void runBenchmarks()
Definition: Benchmark.cpp:456
char ** argv
int main(int argc, char **argv)
BENCHMARK(fbFollyGlobalBenchmarkBaseline)
Definition: Benchmark.cpp:84
BENCHMARK_DRAW_LINE()
auto makeUnpredictable(T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:285
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
Definition: Benchmark.h:258