1*8f0ba417SAndroid Build Coastguard Worker /*
2*8f0ba417SAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project
3*8f0ba417SAndroid Build Coastguard Worker *
4*8f0ba417SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8f0ba417SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8f0ba417SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8f0ba417SAndroid Build Coastguard Worker *
8*8f0ba417SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8f0ba417SAndroid Build Coastguard Worker *
10*8f0ba417SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8f0ba417SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8f0ba417SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8f0ba417SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8f0ba417SAndroid Build Coastguard Worker * limitations under the License.
15*8f0ba417SAndroid Build Coastguard Worker */
16*8f0ba417SAndroid Build Coastguard Worker
17*8f0ba417SAndroid Build Coastguard Worker #include "android-base/function_ref.h"
18*8f0ba417SAndroid Build Coastguard Worker
19*8f0ba417SAndroid Build Coastguard Worker #include <benchmark/benchmark.h>
20*8f0ba417SAndroid Build Coastguard Worker
21*8f0ba417SAndroid Build Coastguard Worker #include <functional>
22*8f0ba417SAndroid Build Coastguard Worker #include <utility>
23*8f0ba417SAndroid Build Coastguard Worker
24*8f0ba417SAndroid Build Coastguard Worker #include <time.h>
25*8f0ba417SAndroid Build Coastguard Worker
26*8f0ba417SAndroid Build Coastguard Worker using android::base::function_ref;
27*8f0ba417SAndroid Build Coastguard Worker
28*8f0ba417SAndroid Build Coastguard Worker template <class Callable, class... Args>
call(Callable && c,Args &&...args)29*8f0ba417SAndroid Build Coastguard Worker [[clang::noinline]] auto call(Callable&& c, Args&&... args) {
30*8f0ba417SAndroid Build Coastguard Worker return c(std::forward<Args>(args)...);
31*8f0ba417SAndroid Build Coastguard Worker }
32*8f0ba417SAndroid Build Coastguard Worker
testFunc(int,const char *,char)33*8f0ba417SAndroid Build Coastguard Worker [[clang::noinline]] static int testFunc(int, const char*, char) {
34*8f0ba417SAndroid Build Coastguard Worker return time(nullptr);
35*8f0ba417SAndroid Build Coastguard Worker }
36*8f0ba417SAndroid Build Coastguard Worker
37*8f0ba417SAndroid Build Coastguard Worker using Func = decltype(testFunc);
38*8f0ba417SAndroid Build Coastguard Worker
BenchmarkFuncRaw(benchmark::State & state)39*8f0ba417SAndroid Build Coastguard Worker static void BenchmarkFuncRaw(benchmark::State& state) {
40*8f0ba417SAndroid Build Coastguard Worker for (auto _ : state) {
41*8f0ba417SAndroid Build Coastguard Worker benchmark::DoNotOptimize(call(testFunc, 1, "1", '1'));
42*8f0ba417SAndroid Build Coastguard Worker }
43*8f0ba417SAndroid Build Coastguard Worker }
44*8f0ba417SAndroid Build Coastguard Worker BENCHMARK(BenchmarkFuncRaw);
45*8f0ba417SAndroid Build Coastguard Worker
BenchmarkFuncPtr(benchmark::State & state)46*8f0ba417SAndroid Build Coastguard Worker static void BenchmarkFuncPtr(benchmark::State& state) {
47*8f0ba417SAndroid Build Coastguard Worker auto ptr = &testFunc;
48*8f0ba417SAndroid Build Coastguard Worker for (auto _ : state) {
49*8f0ba417SAndroid Build Coastguard Worker benchmark::DoNotOptimize(call(ptr, 1, "1", '1'));
50*8f0ba417SAndroid Build Coastguard Worker }
51*8f0ba417SAndroid Build Coastguard Worker }
52*8f0ba417SAndroid Build Coastguard Worker BENCHMARK(BenchmarkFuncPtr);
53*8f0ba417SAndroid Build Coastguard Worker
BenchmarkStdFunction(benchmark::State & state)54*8f0ba417SAndroid Build Coastguard Worker static void BenchmarkStdFunction(benchmark::State& state) {
55*8f0ba417SAndroid Build Coastguard Worker std::function<Func> f(testFunc);
56*8f0ba417SAndroid Build Coastguard Worker for (auto _ : state) {
57*8f0ba417SAndroid Build Coastguard Worker benchmark::DoNotOptimize(call(f, 1, "1", '1'));
58*8f0ba417SAndroid Build Coastguard Worker }
59*8f0ba417SAndroid Build Coastguard Worker }
60*8f0ba417SAndroid Build Coastguard Worker BENCHMARK(BenchmarkStdFunction);
61*8f0ba417SAndroid Build Coastguard Worker
BenchmarkFunctionRef(benchmark::State & state)62*8f0ba417SAndroid Build Coastguard Worker static void BenchmarkFunctionRef(benchmark::State& state) {
63*8f0ba417SAndroid Build Coastguard Worker function_ref<Func> f(testFunc);
64*8f0ba417SAndroid Build Coastguard Worker for (auto _ : state) {
65*8f0ba417SAndroid Build Coastguard Worker benchmark::DoNotOptimize(call(f, 1, "1", '1'));
66*8f0ba417SAndroid Build Coastguard Worker }
67*8f0ba417SAndroid Build Coastguard Worker }
68*8f0ba417SAndroid Build Coastguard Worker BENCHMARK(BenchmarkFunctionRef);
69*8f0ba417SAndroid Build Coastguard Worker
70*8f0ba417SAndroid Build Coastguard Worker namespace {
71*8f0ba417SAndroid Build Coastguard Worker struct BigFunc {
72*8f0ba417SAndroid Build Coastguard Worker char big[128];
operator ()__anon84b648c70111::BigFunc73*8f0ba417SAndroid Build Coastguard Worker [[clang::noinline]] int operator()(int, const char*, char) const { return time(nullptr); }
74*8f0ba417SAndroid Build Coastguard Worker };
75*8f0ba417SAndroid Build Coastguard Worker
76*8f0ba417SAndroid Build Coastguard Worker static BigFunc bigFunc;
77*8f0ba417SAndroid Build Coastguard Worker } // namespace
78*8f0ba417SAndroid Build Coastguard Worker
BenchmarkBigRaw(benchmark::State & state)79*8f0ba417SAndroid Build Coastguard Worker static void BenchmarkBigRaw(benchmark::State& state) {
80*8f0ba417SAndroid Build Coastguard Worker for (auto _ : state) {
81*8f0ba417SAndroid Build Coastguard Worker benchmark::DoNotOptimize(call(bigFunc, 1, "1", '1'));
82*8f0ba417SAndroid Build Coastguard Worker }
83*8f0ba417SAndroid Build Coastguard Worker }
84*8f0ba417SAndroid Build Coastguard Worker BENCHMARK(BenchmarkBigRaw);
85*8f0ba417SAndroid Build Coastguard Worker
BenchmarkBigStdFunction(benchmark::State & state)86*8f0ba417SAndroid Build Coastguard Worker static void BenchmarkBigStdFunction(benchmark::State& state) {
87*8f0ba417SAndroid Build Coastguard Worker std::function<Func> f(bigFunc);
88*8f0ba417SAndroid Build Coastguard Worker for (auto _ : state) {
89*8f0ba417SAndroid Build Coastguard Worker benchmark::DoNotOptimize(call(f, 1, "1", '1'));
90*8f0ba417SAndroid Build Coastguard Worker }
91*8f0ba417SAndroid Build Coastguard Worker }
92*8f0ba417SAndroid Build Coastguard Worker BENCHMARK(BenchmarkBigStdFunction);
93*8f0ba417SAndroid Build Coastguard Worker
BenchmarkBigFunctionRef(benchmark::State & state)94*8f0ba417SAndroid Build Coastguard Worker static void BenchmarkBigFunctionRef(benchmark::State& state) {
95*8f0ba417SAndroid Build Coastguard Worker function_ref<Func> f(bigFunc);
96*8f0ba417SAndroid Build Coastguard Worker for (auto _ : state) {
97*8f0ba417SAndroid Build Coastguard Worker benchmark::DoNotOptimize(call(f, 1, "1", '1'));
98*8f0ba417SAndroid Build Coastguard Worker }
99*8f0ba417SAndroid Build Coastguard Worker }
100*8f0ba417SAndroid Build Coastguard Worker BENCHMARK(BenchmarkBigFunctionRef);
101*8f0ba417SAndroid Build Coastguard Worker
BenchmarkMakeFunctionRef(benchmark::State & state)102*8f0ba417SAndroid Build Coastguard Worker static void BenchmarkMakeFunctionRef(benchmark::State& state) {
103*8f0ba417SAndroid Build Coastguard Worker for (auto _ : state) {
104*8f0ba417SAndroid Build Coastguard Worker benchmark::DoNotOptimize(call<function_ref<Func>>(bigFunc, 1, "1", '1'));
105*8f0ba417SAndroid Build Coastguard Worker }
106*8f0ba417SAndroid Build Coastguard Worker }
107*8f0ba417SAndroid Build Coastguard Worker BENCHMARK(BenchmarkMakeFunctionRef);
108*8f0ba417SAndroid Build Coastguard Worker
BenchmarkMakeStdFunction(benchmark::State & state)109*8f0ba417SAndroid Build Coastguard Worker static void BenchmarkMakeStdFunction(benchmark::State& state) {
110*8f0ba417SAndroid Build Coastguard Worker for (auto _ : state) {
111*8f0ba417SAndroid Build Coastguard Worker benchmark::DoNotOptimize(call<std::function<Func>>(bigFunc, 1, "1", '1'));
112*8f0ba417SAndroid Build Coastguard Worker }
113*8f0ba417SAndroid Build Coastguard Worker }
114*8f0ba417SAndroid Build Coastguard Worker BENCHMARK(BenchmarkMakeStdFunction);
115