From 5196d1e2879db3000e260bccd110efc1d432ac74 Mon Sep 17 00:00:00 2001 From: Adam Simpkins Date: Wed, 31 Oct 2012 12:29:04 -0700 Subject: [PATCH] update function_benchmark to test exception handling Summary: Add benchmarks for throwing an exception versus returning std::exception_ptr or other types of return values. Throwing an exception is very expensive. Calling std::make_exception_ptr() without ever throwing is nearly as bad. The exc_ptr_param_return tests were the ones I was most interested in. (Accepting a std::exception_ptr* argument so the caller can indicate if they want to receive an exception or not.) This is fast if the caller doesn't care about the exception value, but very slow if an error occurs and an exception_ptr is required. Test Plan: ====================================================================== folly/test/function_benchmark/main.cpp relative time/iter iters/s ====================================================================== throw_exception 3.90us 256.25K catch_no_exception 1.88ns 533.25M return_exc_ptr 2.79us 357.85K exc_ptr_param_return 2.83us 353.25K exc_ptr_param_return_null 2.25ns 444.38M return_string 69.39ns 14.41M return_string_noexcept 69.39ns 14.41M return_code 1.50ns 666.54M return_code_noexcept 1.50ns 666.54M Reviewed By: rajat@fb.com FB internal diff: D616474 --- folly/test/function_benchmark/main.cpp | 63 +++++++++++++++++++ .../function_benchmark/test_functions.cpp | 63 ++++++++++++++++++- .../test/function_benchmark/test_functions.h | 28 ++++++++- 3 files changed, 152 insertions(+), 2 deletions(-) diff --git a/folly/test/function_benchmark/main.cpp b/folly/test/function_benchmark/main.cpp index c345ac78..d23e299d 100644 --- a/folly/test/function_benchmark/main.cpp +++ b/folly/test/function_benchmark/main.cpp @@ -197,6 +197,69 @@ BENCHMARK(scope_guard_lambda_local_var, iters) { CHECK_EQ(iters / 2, count); } +BENCHMARK_DRAW_LINE() + +BENCHMARK(throw_exception, iters) { + for (int n = 0; n < iters; ++n) { + try { + throwException(); + } catch (const std::exception& ex) { + } + } +} + +BENCHMARK(catch_no_exception, iters) { + for (int n = 0; n < iters; ++n) { + try { + doNothing(); + } catch (const std::exception& ex) { + } + } +} + +BENCHMARK(return_exc_ptr, iters) { + for (int n = 0; n < iters; ++n) { + returnExceptionPtr(); + } +} + +BENCHMARK(exc_ptr_param_return, iters) { + for (int n = 0; n < iters; ++n) { + std::exception_ptr ex; + exceptionPtrReturnParam(&ex); + } +} + +BENCHMARK(exc_ptr_param_return_null, iters) { + for (int n = 0; n < iters; ++n) { + exceptionPtrReturnParam(nullptr); + } +} + +BENCHMARK(return_string, iters) { + for (int n = 0; n < iters; ++n) { + returnString(); + } +} + +BENCHMARK(return_string_noexcept, iters) { + for (int n = 0; n < iters; ++n) { + returnStringNoExcept(); + } +} + +BENCHMARK(return_code, iters) { + for (int n = 0; n < iters; ++n) { + returnCode(false); + } +} + +BENCHMARK(return_code_noexcept, iters) { + for (int n = 0; n < iters; ++n) { + returnCodeNoExcept(false); + } +} + // main() int main(int argc, char** argv) { diff --git a/folly/test/function_benchmark/test_functions.cpp b/folly/test/function_benchmark/test_functions.cpp index 932ac59b..88727290 100644 --- a/folly/test/function_benchmark/test_functions.cpp +++ b/folly/test/function_benchmark/test_functions.cpp @@ -1,4 +1,19 @@ -// Copyright 2004-present Facebook. All rights reserved. +/* + * Copyright 2012 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "folly/test/function_benchmark/test_functions.h" /* @@ -6,9 +21,55 @@ * gcc won't be able to inline them. */ + +class Exception : public std::exception { + public: + explicit Exception(const std::string& value) : value_(value) {} + virtual ~Exception(void) throw() {} + + virtual const char *what(void) const throw() { + return value_.c_str(); + } + + private: + std::string value_; +}; + void doNothing() { } +void throwException() { + throw Exception("this is a test"); +} + +std::exception_ptr returnExceptionPtr() { + Exception ex("this is a test"); + return std::make_exception_ptr(ex); +} + +void exceptionPtrReturnParam(std::exception_ptr* excReturn) { + if (excReturn) { + Exception ex("this is a test"); + *excReturn = std::make_exception_ptr(ex); + } +} + +std::string returnString() { + return "this is a test"; +} + +std::string returnStringNoExcept() noexcept { + return "this is a test"; +} + +int returnCode(int value) { + return value; +} + +int returnCodeNoExcept(int value) noexcept { + return value; +} + void TestClass::doNothing() { } diff --git a/folly/test/function_benchmark/test_functions.h b/folly/test/function_benchmark/test_functions.h index 586d3238..afe1fde6 100644 --- a/folly/test/function_benchmark/test_functions.h +++ b/folly/test/function_benchmark/test_functions.h @@ -1,9 +1,35 @@ -// Copyright 2004-present Facebook. All rights reserved. +/* + * Copyright 2012 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef TEST_FUNCTIONS_H_ #define TEST_FUNCTIONS_H_ +#include +#include + void doNothing(); +void throwException(); +std::exception_ptr returnExceptionPtr(); +void exceptionPtrReturnParam(std::exception_ptr* excReturn); +std::string returnString(); +std::string returnStringNoExcept() noexcept; +int returnCode(int value); +int returnCodeNoExcept(int value) noexcept; + class TestClass { public: void doNothing(); -- 2.34.1