2 * Copyright 2015 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 -*- */
20 #include <folly/Benchmark.h>
21 #include <folly/Memory.h>
22 #include <gflags/gflags.h>
24 #include <folly/Singleton.h>
26 using namespace folly;
28 // Benchmarking a normal singleton vs a Meyers singleton vs a Folly
29 // singleton. Meyers are insanely fast, but (hopefully) Folly
30 // singletons are fast "enough."
31 int* getMeyersSingleton() {
32 static auto ret = new int(0);
36 int normal_singleton_value = 0;
37 int* getNormalSingleton() {
38 doNotOptimizeAway(&normal_singleton_value);
39 return &normal_singleton_value;
42 struct BenchmarkSingleton {
46 void run4Threads(std::function<void()> f) {
47 std::vector<std::thread> threads;
48 for (size_t i = 0; i < 4; ++ i) {
49 threads.emplace_back(f);
51 for (auto& thread : threads) {
56 void normalSingleton(size_t n) {
57 for (size_t i = 0; i < n; ++ i) {
58 doNotOptimizeAway(getNormalSingleton());
62 BENCHMARK(NormalSingleton, n) {
66 BENCHMARK(NormalSingleton4Threads, n) {
72 void meyersSingleton(size_t n) {
73 for (size_t i = 0; i < n; ++i) {
74 doNotOptimizeAway(getMeyersSingleton());
79 BENCHMARK(MeyersSingleton, n) {
83 BENCHMARK(MeyersSingleton4Threads, n) {
89 struct BenchmarkTag {};
90 template <typename T, typename Tag = detail::DefaultTag>
91 using SingletonBenchmark = Singleton <T, Tag, BenchmarkTag>;
95 struct TryGetFastTag{};
97 SingletonBenchmark<BenchmarkSingleton, GetTag> benchmark_singleton_get;
98 SingletonBenchmark<BenchmarkSingleton, TryGetTag> benchmark_singleton_try_get;
99 SingletonBenchmark<BenchmarkSingleton, TryGetFastTag>
100 benchmark_singleton_try_get_fast;
102 void follySingletonRaw(size_t n) {
103 for (size_t i = 0; i < n; ++i) {
104 SingletonBenchmark<BenchmarkSingleton, GetTag>::get();
108 BENCHMARK(FollySingletonRaw, n) {
109 follySingletonRaw(n);
112 BENCHMARK(FollySingletonRaw4Threads, n) {
114 follySingletonRaw(n);
118 void follySingletonTryGet(size_t n) {
119 for (size_t i = 0; i < n; ++i) {
120 SingletonBenchmark<BenchmarkSingleton, TryGetTag>::try_get();
124 BENCHMARK(FollySingletonTryGet, n) {
125 follySingletonTryGet(n);
128 BENCHMARK(FollySingletonTryGet4Threads, n) {
130 follySingletonTryGet(n);
134 void follySingletonTryGetFast(size_t n) {
135 for (size_t i = 0; i < n; ++i) {
136 SingletonBenchmark<BenchmarkSingleton, TryGetFastTag>::try_get_fast();
140 BENCHMARK(FollySingletonTryGetFast, n) {
141 follySingletonTryGetFast(n);
144 BENCHMARK(FollySingletonTryGetFast4Threads, n) {
146 follySingletonTryGetFast(n);
150 int main(int argc, char** argv) {
151 gflags::ParseCommandLineFlags(&argc, &argv, true);
152 gflags::SetCommandLineOptionWithMode(
153 "bm_min_usec", "100000", gflags::SET_FLAG_IF_DEFAULT
156 folly::runBenchmarks();