/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2011-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <folly/test/function_benchmark/benchmark_impl.h>
#include <folly/test/function_benchmark/test_functions.h>
+#include <glog/logging.h>
+
#include <folly/Benchmark.h>
#include <folly/ScopeGuard.h>
-#include <gflags/gflags.h>
-#include <glog/logging.h>
+#include <folly/portability/GFlags.h>
-using folly::ScopeGuard;
using folly::makeGuard;
// Declare the bm_max_iters flag from folly/Benchmark.cpp
BM_std_function_invoke_impl(iters, doNothing);
}
+// Invoking a function through a folly::Function object
+BENCHMARK(Function_invoke, iters) {
+ BM_Function_invoke_impl(iters, doNothing);
+}
+
// Invoking a member function through a member function pointer
BENCHMARK(mem_fn_invoke, iters) {
TestClass tc;
}
}
+// Creating a folly::Function object from a function pointer, and
+// invoking it
+BENCHMARK(Function_create_invoke, iters) {
+ for (size_t n = 0; n < iters; ++n) {
+ folly::Function<void()> fn = doNothing;
+ fn();
+ }
+}
+
// Creating a pointer-to-member and invoking it
BENCHMARK(mem_fn_create_invoke, iters) {
TestClass tc;
BENCHMARK(scope_guard_std_function, iters) {
std::function<void()> fn(doNothing);
for (size_t n = 0; n < iters; ++n) {
- ScopeGuard g = makeGuard(fn);
+ auto g = makeGuard(fn);
+ (void)g;
}
}
// but create the ScopeGuard with an rvalue to a std::function
BENCHMARK(scope_guard_std_function_rvalue, iters) {
for (size_t n = 0; n < iters; ++n) {
- ScopeGuard g = makeGuard(std::function<void()>(doNothing));
+ auto g = makeGuard(std::function<void()>(doNothing));
+ (void)g;
+ }
+}
+
+// Using ScopeGuard to invoke a folly::Function,
+// but create the ScopeGuard with an rvalue to a folly::Function
+BENCHMARK(scope_guard_Function_rvalue, iters) {
+ for (size_t n = 0; n < iters; ++n) {
+ auto g = makeGuard(folly::Function<void()>(doNothing));
+ (void)g;
}
}
// Using ScopeGuard to invoke a function pointer
BENCHMARK(scope_guard_fn_ptr, iters) {
for (size_t n = 0; n < iters; ++n) {
- ScopeGuard g = makeGuard(doNothing);
+ auto g = makeGuard(doNothing);
+ (void)g;
}
}
// Using ScopeGuard to invoke a lambda that does nothing
BENCHMARK(scope_guard_lambda_noop, iters) {
for (size_t n = 0; n < iters; ++n) {
- ScopeGuard g = makeGuard([] {});
+ auto g = makeGuard([] {});
+ (void)g;
}
}
// Using ScopeGuard to invoke a lambda that invokes a function
BENCHMARK(scope_guard_lambda_function, iters) {
for (size_t n = 0; n < iters; ++n) {
- ScopeGuard g = makeGuard([] { doNothing(); });
+ auto g = makeGuard([] { doNothing(); });
+ (void)g;
}
}
BENCHMARK(scope_guard_lambda_local_var, iters) {
uint32_t count = 0;
for (size_t n = 0; n < iters; ++n) {
- ScopeGuard g = makeGuard([&] {
+ auto g = makeGuard([&] {
// Increment count if n is odd. Without this conditional check
// (i.e., if we just increment count each time through the loop),
// gcc is smart enough to optimize the entire loop away, and just set
++count;
}
});
+ (void)g;
}
// Check that the value of count is what we expect.
}
}
+BENCHMARK_DRAW_LINE()
+
+BENCHMARK(std_function_create_move_invoke, iters) {
+ LargeClass a;
+ for (size_t i = 0; i < iters; ++i) {
+ std::function<void()> f(a);
+ invoke(std::move(f));
+ }
+}
+
+BENCHMARK(Function_create_move_invoke, iters) {
+ LargeClass a;
+ for (size_t i = 0; i < iters; ++i) {
+ folly::Function<void()> f(a);
+ invoke(std::move(f));
+ }
+}
+
+BENCHMARK(std_function_create_move_invoke_ref, iters) {
+ LargeClass a;
+ for (size_t i = 0; i < iters; ++i) {
+ std::function<void()> f(std::ref(a));
+ invoke(std::move(f));
+ }
+}
+
+BENCHMARK(Function_create_move_invoke_ref, iters) {
+ LargeClass a;
+ for (size_t i = 0; i < iters; ++i) {
+ folly::Function<void()> f(std::ref(a));
+ invoke(std::move(f));
+ }
+}
+
// main()
int main(int argc, char** argv) {