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.
16 /* -*- Mode: C++; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
18 #include <folly/Singleton.h>
23 #include <folly/Benchmark.h>
24 #include <folly/Memory.h>
25 #include <folly/portability/GFlags.h>
27 FOLLY_GCC_DISABLE_WARNING("-Wdeprecated-declarations")
29 using namespace folly;
31 // Benchmarking a normal singleton vs a Meyers singleton vs a Folly
32 // singleton. Meyers are insanely fast, but (hopefully) Folly
33 // singletons are fast "enough."
34 int* getMeyersSingleton() {
35 static auto ret = new int(0);
39 int normal_singleton_value = 0;
40 int* getNormalSingleton() {
41 doNotOptimizeAway(&normal_singleton_value);
42 return &normal_singleton_value;
45 struct BenchmarkSingleton {
49 void run4Threads(std::function<void()> f) {
50 std::vector<std::thread> threads;
51 for (size_t i = 0; i < 4; ++ i) {
52 threads.emplace_back(f);
54 for (auto& thread : threads) {
59 void normalSingleton(size_t n) {
60 for (size_t i = 0; i < n; ++ i) {
61 doNotOptimizeAway(getNormalSingleton());
65 BENCHMARK(NormalSingleton, n) {
69 BENCHMARK(NormalSingleton4Threads, n) {
75 void meyersSingleton(size_t n) {
76 for (size_t i = 0; i < n; ++i) {
77 doNotOptimizeAway(getMeyersSingleton());
82 BENCHMARK(MeyersSingleton, n) {
86 BENCHMARK(MeyersSingleton4Threads, n) {
92 struct BenchmarkTag {};
93 template <typename T, typename Tag = detail::DefaultTag>
94 using SingletonBenchmark = Singleton <T, Tag, BenchmarkTag>;
98 struct TryGetFastTag{};
100 SingletonBenchmark<BenchmarkSingleton, GetTag> benchmark_singleton_get;
101 SingletonBenchmark<BenchmarkSingleton, TryGetTag> benchmark_singleton_try_get;
102 SingletonBenchmark<BenchmarkSingleton, TryGetFastTag>
103 benchmark_singleton_try_get_fast;
105 void follySingletonRaw(size_t n) {
106 for (size_t i = 0; i < n; ++i) {
107 SingletonBenchmark<BenchmarkSingleton, GetTag>::get();
111 BENCHMARK(FollySingletonRaw, n) {
112 follySingletonRaw(n);
115 BENCHMARK(FollySingletonRaw4Threads, n) {
117 follySingletonRaw(n);
121 void follySingletonTryGet(size_t n) {
122 for (size_t i = 0; i < n; ++i) {
123 SingletonBenchmark<BenchmarkSingleton, TryGetTag>::try_get();
127 BENCHMARK(FollySingletonTryGet, n) {
128 follySingletonTryGet(n);
131 BENCHMARK(FollySingletonTryGet4Threads, n) {
133 follySingletonTryGet(n);
137 void follySingletonTryGetFast(size_t n) {
138 for (size_t i = 0; i < n; ++i) {
139 SingletonBenchmark<BenchmarkSingleton, TryGetFastTag>::try_get_fast();
143 BENCHMARK(FollySingletonTryGetFast, n) {
144 follySingletonTryGetFast(n);
147 BENCHMARK(FollySingletonTryGetFast4Threads, n) {
149 follySingletonTryGetFast(n);
153 int main(int argc, char** argv) {
154 gflags::ParseCommandLineFlags(&argc, &argv, true);
155 gflags::SetCommandLineOptionWithMode(
156 "bm_min_usec", "100000", gflags::SET_FLAG_IF_DEFAULT
159 folly::runBenchmarks();