When calling bound method this->UpdateB = std::bind(&Test::Update, this); (called using test.UpdateB()) its overall performance is considerably slower than calling the function directly. test.Update()
The performance decrease seams to also effect the work done in the method.
Using the site quick-bench I run the snippet below and get the following result
#include <functional>
#include <benchmark/benchmark.h>
typedef unsigned u32;
typedef uint64_t u64;
constexpr auto nP = nullptr;
constexpr bool _F = false;
constexpr bool _T = true;
constexpr u64 HIGH_LOAD = 1000000000;
constexpr u64 LOW_LOAD = 10;
struct Test {
u32 counter{100000};
u64 soak{0};
u64 load{10};
bool isAlive{_T};
std::function<bool()> UpdateB;
Test() { UpdateB = std::bind( &Test::Update, this); }
bool Update() {
if (counter > 0) { counter --; }
u64 i = load;
while(i--) { soak += 1; }
isAlive = counter > 0;
return isAlive;
}
};
static void DirectCallLowLoad(benchmark::State& state) {
Test test;
test.load = LOW_LOAD;
for (auto _ : state) { test.Update(); }
}
BENCHMARK(DirectCallLowLoad);
static void DirectCallHighLoad(benchmark::State& state) {
Test test;
test.load = HIGH_LOAD;
for (auto _ : state) { test.Update(); }
}
BENCHMARK(DirectCallHighLoad);
static void BoundCallLowLoad(benchmark::State& state) {
Test test;
test.load = LOW_LOAD;
for (auto _ : state) { test.UpdateB(); }
}
BENCHMARK(BoundCallLowLoad);
static void BoundCallHighLoad(benchmark::State& state) {
Test test;
test.load = HIGH_LOAD;
for (auto _ : state) { test.UpdateB(); }
}
BENCHMARK(BoundCallHighLoad);
The expectation is that...
BoundCallHighLoadperformance would get closer toDirectCallHighLoadas the call overhead has less effect compared to the method's load .DirectCallLowLoadperformance would be significantly better thanDirectCallHighLoad(same for bound calls.)Bound calls would not be almost 5 times slower than direct calls.
What is wrong with my code?
Why are bound calls so slow?
If I use
std::function<bool(Test*)> UpdateB;
Test() { UpdateB = &Test::Update; } // Test constructor
// call using
test.UpdateB(&test);
it gets even worse, the call test.UpdateB(&test); is many magnitudes slower than the direct call test.Update() with processing load making little to no difference.

