update function_benchmark to test exception handling
authorAdam Simpkins <simpkins@fb.com>
Wed, 31 Oct 2012 19:29:04 +0000 (12:29 -0700)
committerJordan DeLong <jdelong@fb.com>
Sun, 16 Dec 2012 22:42:00 +0000 (14:42 -0800)
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
folly/test/function_benchmark/test_functions.cpp
folly/test/function_benchmark/test_functions.h

index c345ac7..d23e299 100644 (file)
@@ -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) {
index 932ac59..8872729 100644 (file)
@@ -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() {
 }
 
index 586d323..afe1fde 100644 (file)
@@ -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 <exception>
+#include <string>
+
 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();