I'm writing a template function which involved usage of f = std::bind(std::bind(std::bind(...)))
.
but I'm not sure whether the c++ compiler is smart enough to unfold the calling chain.
What I mean is:
- when creating functor
f
, is there multiple std::bind()
invoked at runtime?
- when calling
f()
, does it involves calling
multiple operator()
at different layers of bind_functor object.
As a simple example: Does f2()
run slightly faster than f1()
?
#include <functional>
int add(int a, int b) {
return a + b;
}
int main() {
using namespace std::placeholders;
auto f1 = std::bind(std::bind(&add, 1, _1), 2);
auto f2 = std::bind(&add, 1, 2);
return 0;
}
Update:
I did some experiment. It seems f2()
does run faster than f1()
. And if you use std::function
, it is even slower. Here is the experimental code (ubuntu/gcc 7.5.0, with optimization enabled. Without optimization, f2
is the slowest.). On my computer, the output is:
f1: 16851813
f2: 17567904
f3: 30655284
Here is the code (updated according to the comment of Nate):
#include <chrono>
#include <iostream>
#include <functional>
int add(int a, int b, int c) {
return a + b + c;
}
int main() {
using namespace std::placeholders;
auto f1 = std::bind(std::bind(&add, 1, _1, _2), 2, _1);
auto f2 = std::bind(&add, 1, 2, _1);
std::function<int(int)> f3 = std::bind(&add, 1, 2, _1);
const int N = 10000000;
volatile int x = 0;
{
auto begin = std::chrono::system_clock::now();
for (int n = 0; n < N; n++) {
x = f1(x);
}
auto end = std::chrono::system_clock::now();
auto d = end - begin;
std::cout << "f1: " << d.count() << std::endl;
}
x = 0;
{
auto begin = std::chrono::system_clock::now();
for (int n = 0; n < N; n++) {
x = f2(x);
}
auto end = std::chrono::system_clock::now();
auto d = end - begin;
std::cout << "f2: " << d.count() << std::endl;
}
x = 0;
{
auto begin = std::chrono::system_clock::now();
for (int n = 0; n < N; n++) {
x = f3(x);
}
auto end = std::chrono::system_clock::now();
auto d = end - begin;
std::cout << "f3: " << d.count() << std::endl;
}
return 0;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…