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 #include <folly/ExceptionWrapper.h>
24 #include <folly/Benchmark.h>
25 #include <folly/portability/GFlags.h>
27 DEFINE_int32(num_threads, 32, "Number of threads to run concurrency "
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
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);
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);
55 BENCHMARK(exception_ptr_create_and_test_concurrent, iters) {
56 std::atomic<bool> go(false);
57 std::vector<std::thread> threads;
59 for (int t = 0; t < FLAGS_num_threads; ++t) {
60 threads.emplace_back([&go, iters] {
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);
72 for (auto& t : threads) {
77 BENCHMARK_RELATIVE(exception_wrapper_create_and_test_concurrent, iters) {
78 std::atomic<bool> go(false);
79 std::vector<std::thread> threads;
81 for (int t = 0; t < FLAGS_num_threads; ++t) {
82 threads.emplace_back([&go, iters] {
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);
94 for (auto& t : threads) {
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.
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);
111 std::rethrow_exception(ep);
112 } catch (std::runtime_error&) {
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);
123 } catch (std::runtime_error&) {
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);
138 BENCHMARK_DRAW_LINE()
140 BENCHMARK(exception_ptr_create_and_throw_concurrent, iters) {
141 std::atomic<bool> go(false);
142 std::vector<std::thread> threads;
144 for (int t = 0; t < FLAGS_num_threads; ++t) {
145 threads.emplace_back([&go, iters] {
147 std::runtime_error e("payload");
148 for (size_t i = 0; i < iters; ++i) {
149 auto ep = std::make_exception_ptr(e);
151 std::rethrow_exception(ep);
152 } catch (std::runtime_error&) {
159 for (auto& t : threads) {
164 BENCHMARK_RELATIVE(exception_wrapper_create_and_throw_concurrent, iters) {
165 std::atomic<bool> go(false);
166 std::vector<std::thread> threads;
168 for (int t = 0; t < FLAGS_num_threads; ++t) {
169 threads.emplace_back([&go, iters] {
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);
176 } catch (std::runtime_error&) {
183 for (auto& t : threads) {
188 BENCHMARK_RELATIVE(exception_wrapper_create_and_cast_concurrent, iters) {
189 std::atomic<bool> go(false);
190 std::vector<std::thread> threads;
192 for (int t = 0; t < FLAGS_num_threads; ++t) {
193 threads.emplace_back([&go, iters] {
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);
205 for (auto& t : threads) {
210 int main(int argc, char *argv[]) {
211 gflags::ParseCommandLineFlags(&argc, &argv, true);
212 folly::runBenchmarks();
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 ============================================================================