2 * Copyright 2017 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/Benchmark.h>
18 #include <folly/Foreach.h>
19 #include <folly/String.h>
25 using namespace folly;
33 BENCHMARK(bmFun) { fun(); }
34 BENCHMARK(bmRepeatedFun, n) {
35 FOR_EACH_RANGE (i, 0, n) {
49 BENCHMARK(optimizerCanDiscardTrivial, n) {
51 for (long i = 0; i < n; ++i) {
52 for (long j = 0; j < 10000; ++j) {
58 BENCHMARK(optimizerCanPowerReduceInner1Trivial, n) {
60 for (long i = 0; i < n; ++i) {
61 for (long j = 0; j < 10000; ++j) {
68 BENCHMARK(optimizerCanPowerReduceInner2Trivial, n) {
70 for (long i = 0; i < n; ++i) {
72 for (long j = 0; j < 10000; ++j) {
79 BENCHMARK(optimizerDisabled1Trivial, n) {
81 for (long i = 0; i < n; ++i) {
82 for (long j = 0; j < 10000; ++j) {
89 BENCHMARK(optimizerDisabled2Trivial, n) {
91 for (long i = 0; i < n; ++i) {
93 for (long j = 0; j < 10000; ++j) {
101 BENCHMARK(optimizerCanPowerReduceInner1TrivialPtr, n) {
103 for (long i = 0; i < n; ++i) {
104 for (long j = 0; j < 10000; ++j) {
107 doNotOptimizeAway(&x);
111 BENCHMARK(optimizerCanPowerReduceInner2TrivialPtr, n) {
113 for (long i = 0; i < n; ++i) {
114 makeUnpredictable(i);
115 for (long j = 0; j < 10000; ++j) {
119 doNotOptimizeAway(&x);
122 BENCHMARK(optimizerDisabled1TrivialPtr, n) {
124 for (long i = 0; i < n; ++i) {
125 for (long j = 0; j < 10000; ++j) {
127 doNotOptimizeAway(&x);
133 class NonTrivialLong {
135 explicit NonTrivialLong(long v) : value_(v) {}
136 virtual ~NonTrivialLong() {}
141 void operator+=(long rhs) {
144 void operator+=(const NonTrivialLong& rhs) {
145 value_ += rhs.value_;
147 bool operator<(long rhs) {
150 NonTrivialLong operator+(const NonTrivialLong& rhs) {
151 return NonTrivialLong(value_ + rhs.value_);
160 BENCHMARK(optimizerCanDiscardNonTrivial, n) {
162 for (NonTrivialLong i(0); i < n; ++i) {
163 for (NonTrivialLong j(0); j < 10000; ++j) {
169 BENCHMARK(optimizerCanPowerReduceInner1NonTrivial, n) {
171 for (NonTrivialLong i(0); i < n; ++i) {
172 for (NonTrivialLong j(0); j < 10000; ++j) {
175 doNotOptimizeAway(x);
179 BENCHMARK(optimizerCanPowerReduceInner2NonTrivial, n) {
181 for (NonTrivialLong i(0); i < n; ++i) {
182 makeUnpredictable(i);
183 for (NonTrivialLong j(0); j < 10000; ++j) {
187 doNotOptimizeAway(x);
190 BENCHMARK(optimizerDisabled1NonTrivial, n) {
192 for (NonTrivialLong i(0); i < n; ++i) {
193 for (NonTrivialLong j(0); j < 10000; ++j) {
195 doNotOptimizeAway(x);
200 BENCHMARK(optimizerDisabled2NonTrivial, n) {
202 for (NonTrivialLong i(0); i < n; ++i) {
203 makeUnpredictable(i);
204 for (NonTrivialLong j(0); j < 10000; ++j) {
205 makeUnpredictable(j);
209 doNotOptimizeAway(x);
212 BENCHMARK(optimizerCanPowerReduceInner1NonTrivialPtr, n) {
214 for (NonTrivialLong i(0); i < n; ++i) {
215 for (NonTrivialLong j(0); j < 10000; ++j) {
218 doNotOptimizeAway(&x);
222 BENCHMARK(optimizerCanPowerReduceInner2NonTrivialPtr, n) {
224 for (NonTrivialLong i(0); i < n; ++i) {
225 makeUnpredictable(i);
226 for (NonTrivialLong j(0); j < 10000; ++j) {
230 doNotOptimizeAway(&x);
233 BENCHMARK(optimizerDisabled1NonTrivialPtr, n) {
235 for (NonTrivialLong i(0); i < n; ++i) {
236 for (NonTrivialLong j(0); j < 10000; ++j) {
238 doNotOptimizeAway(&x);
243 BENCHMARK_DRAW_LINE()
245 BENCHMARK(baselinevector) {
252 FOR_EACH_RANGE (i, 0, 100) {
257 BENCHMARK_RELATIVE(bmVector) {
259 FOR_EACH_RANGE (i, 0, 100) {
260 v.resize(v.size() + 1, 42);
264 BENCHMARK_DRAW_LINE()
266 BENCHMARK(superslow) {
270 BENCHMARK_DRAW_LINE()
276 BENCHMARK_MULTI(multiSimple) {
277 FOR_EACH_RANGE (i, 0, 10) {
283 BENCHMARK_RELATIVE_MULTI(multiSimpleRel) {
284 FOR_EACH_RANGE (i, 0, 10) {
291 BENCHMARK_MULTI(multiIterArgs, iter) {
292 FOR_EACH_RANGE (i, 0, 10 * iter) {
298 BENCHMARK_RELATIVE_MULTI(multiIterArgsRel, iter) {
299 FOR_EACH_RANGE (i, 0, 10 * iter) {
306 unsigned paramMulti(unsigned iter, unsigned num) {
307 for (unsigned i = 0; i < iter; ++i) {
308 for (unsigned j = 0; j < num; ++j) {
315 unsigned paramMultiRel(unsigned iter, unsigned num) {
316 for (unsigned i = 0; i < iter; ++i) {
317 for (unsigned j = 0; j < num; ++j) {
325 BENCHMARK_PARAM_MULTI(paramMulti, 1);
326 BENCHMARK_RELATIVE_PARAM_MULTI(paramMultiRel, 1);
328 BENCHMARK_PARAM_MULTI(paramMulti, 5);
329 BENCHMARK_RELATIVE_PARAM_MULTI(paramMultiRel, 5);
331 BENCHMARK_DRAW_LINE();
333 BENCHMARK(BenchmarkSuspender_dismissing_void, iter) {
334 BenchmarkSuspender braces;
337 vector<size_t> v(1 << 12, 0);
338 iota(v.begin(), v.end(), 0);
339 shuffle(v.begin(), v.end(), rng);
340 braces.dismissing([&] {
341 sort(v.begin(), v.end());
346 BENCHMARK(BenchmarkSuspender_dismissing_value, iter) {
347 BenchmarkSuspender braces;
350 vector<size_t> v(1 << 12, 0);
351 iota(v.begin(), v.end(), 0);
352 shuffle(v.begin(), v.end(), rng);
353 auto s = braces.dismissing([&] {
354 sort(v.begin(), v.end());
355 return accumulate(v.begin(), v.end(), 0, [](size_t a, size_t e) {
359 doNotOptimizeAway(s);
363 int main(int argc, char** argv) {
364 gflags::ParseCommandLineFlags(&argc, &argv, true);
366 runBenchmarksOnFlag();