Fix copyright lines for Bits.h and move BitsBenchmark.cpp
[folly.git] / folly / test / ExceptionWrapperBenchmark.cpp
1 /*
2  * Copyright 2017 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/ExceptionWrapper.h>
17
18 #include <atomic>
19 #include <exception>
20 #include <stdexcept>
21 #include <thread>
22 #include <vector>
23
24 #include <folly/Benchmark.h>
25 #include <folly/portability/GFlags.h>
26
27 DEFINE_int32(num_threads, 32, "Number of threads to run concurrency "
28                               "benchmarks");
29
30 /*
31  * Use case 1: Library wraps errors in either exception_wrapper or
32  * exception_ptr, but user does not care what the exception is after learning
33  * that there is one.
34  */
35 BENCHMARK(exception_ptr_create_and_test, iters) {
36   std::runtime_error e("payload");
37   for (size_t i = 0; i < iters; ++i) {
38     auto ep = std::make_exception_ptr(e);
39     bool b = static_cast<bool>(ep);
40     folly::doNotOptimizeAway(b);
41   }
42 }
43
44 BENCHMARK_RELATIVE(exception_wrapper_create_and_test, iters) {
45   std::runtime_error e("payload");
46   for (size_t i = 0; i < iters; ++i) {
47     auto ew = folly::make_exception_wrapper<std::runtime_error>(e);
48     bool b = static_cast<bool>(ew);
49     folly::doNotOptimizeAway(b);
50   }
51 }
52
53 BENCHMARK_DRAW_LINE()
54
55 BENCHMARK(exception_ptr_create_and_test_concurrent, iters) {
56   std::atomic<bool> go(false);
57   std::vector<std::thread> threads;
58   BENCHMARK_SUSPEND {
59     for (int t = 0; t < FLAGS_num_threads; ++t) {
60       threads.emplace_back([&go, iters] {
61         while (!go) { }
62         std::runtime_error e("payload");
63         for (size_t i = 0; i < iters; ++i) {
64           auto ep = std::make_exception_ptr(e);
65           bool b = static_cast<bool>(ep);
66           folly::doNotOptimizeAway(b);
67         }
68       });
69     }
70   }
71   go.store(true);
72   for (auto& t : threads) {
73     t.join();
74   }
75 }
76
77 BENCHMARK_RELATIVE(exception_wrapper_create_and_test_concurrent, iters) {
78   std::atomic<bool> go(false);
79   std::vector<std::thread> threads;
80   BENCHMARK_SUSPEND {
81     for (int t = 0; t < FLAGS_num_threads; ++t) {
82       threads.emplace_back([&go, iters] {
83         while (!go) { }
84         std::runtime_error e("payload");
85         for (size_t i = 0; i < iters; ++i) {
86           auto ew = folly::make_exception_wrapper<std::runtime_error>(e);
87           bool b = static_cast<bool>(ew);
88           folly::doNotOptimizeAway(b);
89         }
90       });
91     }
92   }
93   go.store(true);
94   for (auto& t : threads) {
95     t.join();
96   }
97 }
98
99 BENCHMARK_DRAW_LINE()
100
101 /*
102  * Use case 2: Library wraps errors in either exception_wrapper or
103  * exception_ptr, and user wants to handle std::runtime_error. This can be done
104  * either by rehtrowing or with dynamic_cast.
105  */
106 BENCHMARK(exception_ptr_create_and_throw, iters) {
107   std::runtime_error e("payload");
108   for (size_t i = 0; i < iters; ++i) {
109     auto ep = std::make_exception_ptr(e);
110     try {
111       std::rethrow_exception(ep);
112     } catch (std::runtime_error&) {
113     }
114   }
115 }
116
117 BENCHMARK_RELATIVE(exception_wrapper_create_and_throw, iters) {
118   std::runtime_error e("payload");
119   for (size_t i = 0; i < iters; ++i) {
120     auto ew = folly::make_exception_wrapper<std::runtime_error>(e);
121     try {
122       ew.throw_exception();
123     } catch (std::runtime_error&) {
124     }
125   }
126 }
127
128 BENCHMARK_RELATIVE(exception_wrapper_create_and_cast, iters) {
129   std::runtime_error e("payload");
130   for (size_t i = 0; i < iters; ++i) {
131     auto ew = folly::make_exception_wrapper<std::runtime_error>(e);
132     bool b = ew.is_compatible_with<std::runtime_error>();
133     folly::doNotOptimizeAway(b);
134   }
135 }
136
137
138 BENCHMARK_DRAW_LINE()
139
140 BENCHMARK(exception_ptr_create_and_throw_concurrent, iters) {
141   std::atomic<bool> go(false);
142   std::vector<std::thread> threads;
143   BENCHMARK_SUSPEND {
144     for (int t = 0; t < FLAGS_num_threads; ++t) {
145       threads.emplace_back([&go, iters] {
146         while (!go) { }
147         std::runtime_error e("payload");
148         for (size_t i = 0; i < iters; ++i) {
149           auto ep = std::make_exception_ptr(e);
150           try {
151             std::rethrow_exception(ep);
152           } catch (std::runtime_error&) {
153           }
154         }
155       });
156     }
157   }
158   go.store(true);
159   for (auto& t : threads) {
160     t.join();
161   }
162 }
163
164 BENCHMARK_RELATIVE(exception_wrapper_create_and_throw_concurrent, iters) {
165   std::atomic<bool> go(false);
166   std::vector<std::thread> threads;
167   BENCHMARK_SUSPEND {
168     for (int t = 0; t < FLAGS_num_threads; ++t) {
169       threads.emplace_back([&go, iters] {
170         while (!go) { }
171         std::runtime_error e("payload");
172         for (size_t i = 0; i < iters; ++i) {
173           auto ew = folly::make_exception_wrapper<std::runtime_error>(e);
174           try {
175             ew.throw_exception();
176           } catch (std::runtime_error&) {
177           }
178         }
179       });
180     }
181   }
182   go.store(true);
183   for (auto& t : threads) {
184     t.join();
185   }
186 }
187
188 BENCHMARK_RELATIVE(exception_wrapper_create_and_cast_concurrent, iters) {
189   std::atomic<bool> go(false);
190   std::vector<std::thread> threads;
191   BENCHMARK_SUSPEND {
192     for (int t = 0; t < FLAGS_num_threads; ++t) {
193       threads.emplace_back([&go, iters] {
194         while (!go) { }
195         std::runtime_error e("payload");
196         for (size_t i = 0; i < iters; ++i) {
197           auto ew = folly::make_exception_wrapper<std::runtime_error>(e);
198           bool b = ew.is_compatible_with<std::runtime_error>();
199           folly::doNotOptimizeAway(b);
200         }
201       });
202     }
203   }
204   go.store(true);
205   for (auto& t : threads) {
206     t.join();
207   }
208 }
209
210 int main(int argc, char *argv[]) {
211   gflags::ParseCommandLineFlags(&argc, &argv, true);
212   folly::runBenchmarks();
213   return 0;
214 }
215
216 /*
217 _bin/folly/test/exception_wrapper_benchmark --bm_min_iters=100000
218 ============================================================================
219 folly/test/ExceptionWrapperBenchmark.cpp        relative  time/iter  iters/s
220 ============================================================================
221 exception_ptr_create_and_test                                2.03us  492.88K
222 exception_wrapper_create_and_test               2542.59%    79.80ns   12.53M
223 ----------------------------------------------------------------------------
224 exception_ptr_create_and_test_concurrent                   162.39us    6.16K
225 exception_wrapper_create_and_test_concurrent    95847.91%   169.43ns    5.90M
226 ----------------------------------------------------------------------------
227 exception_ptr_create_and_throw                               4.24us  236.06K
228 exception_wrapper_create_and_throw               141.15%     3.00us  333.20K
229 exception_wrapper_create_and_cast               5321.54%    79.61ns   12.56M
230 ----------------------------------------------------------------------------
231 exception_ptr_create_and_throw_concurrent                  330.88us    3.02K
232 exception_wrapper_create_and_throw_concurrent    143.66%   230.32us    4.34K
233 exception_wrapper_create_and_cast_concurrent    194828.54%   169.83ns    5.89M
234 ============================================================================
235 */