Skip to content

Instantly share code, notes, and snippets.

@daverigby
Last active January 22, 2019 20:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daverigby/371f4032fc622153a380a718976e50d1 to your computer and use it in GitHub Desktop.
Save daverigby/371f4032fc622153a380a718976e50d1 to your computer and use it in GitHub Desktop.
#include <functional>
using Raw = int (*)(const char* key, size_t klen,
const char* val, size_t vlen);
using Func = std::function<int(const char* key, size_t klen,
const char* val, size_t vlen)>;
volatile int count = 0;
int add_stats(const char* key, size_t klen,
const char* val, size_t vlen) __attribute__((noinline));
int add_stats(const char* key, size_t klen,
const char* val, size_t vlen) {
return count++;
}
int stats_raw(const Raw& cb, const char* key, size_t klen, const char* val, size_t vlen) __attribute__((noinline));
int stats_raw(const Raw& cb, const char* key, size_t klen, const char* val, size_t vlen) {
return cb(key, klen, val, vlen);
}
int stats_func(const Func& cb, const char* key, size_t klen, const char* val, size_t vlen) __attribute__((noinline));
int stats_func(const Func& cb, const char* key, size_t klen, const char* val, size_t vlen) {
return cb(key, klen, val, vlen);
}
int stats_func_by_va(Func cb, const char* key, size_t klen, const char* val, size_t vlen) __attribute__((noinline));
int stats_func_by_val(Func cb, const char* key, size_t klen, const char* val, size_t vlen) {
return cb(key, klen, val, vlen);
}
auto makeExitBorderGuard = [](auto&& wrapped) {
return [wrapped](auto&&... args) {
return wrapped(std::forward<decltype(args)>(args)...);
};
};
static void CallbackRaw(benchmark::State& state) {
// Code inside this loop is measured repeatedly
for (auto _ : state) {
stats_raw(add_stats, "key", 3, "value", 5);
}
}
// Register the function as a benchmark
BENCHMARK(CallbackRaw);
static void CallbackFunction(benchmark::State& state) {
auto cb = Func(add_stats);
// Code inside this loop is measured repeatedly
for (auto _ : state) {
stats_func(cb, "key", 3, "value", 5);
}
}
BENCHMARK(CallbackFunction);
static void CallbackFunctionByValue(benchmark::State& state) {
auto cb = Func(add_stats);
// Code inside this loop is measured repeatedly
for (auto _ : state) {
stats_func_by_val(cb, "key", 3, "value", 5);
}
}
BENCHMARK(CallbackFunctionByValue);
static void WrappedCallbackFunction(benchmark::State& state) {
// Note: defining borderGuard as std::function (via Func()) makes noticable
// difference in perf - assume it was previously creating a std::function inside the loop
auto borderGuard = Func(makeExitBorderGuard(add_stats));
// Code inside this loop is measured repeatedly
for (auto _ : state) {
stats_func(borderGuard, "key", 3, "value", 5);
}
}
BENCHMARK(WrappedCallbackFunction);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment