std :: bind与lambda性能 [英] std::bind vs lambda performance

查看:980
本文介绍了std :: bind与lambda性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 使用命名空间std; 
template< int N = 1,Class Fun,class ... Args>
void timeExec(string name,Fun fun,Args ... args){

auto start = chrono :: steady_clock :: now();

for(int i = 0; i fun(args ...);
}

auto end = chrono :: steady_clock :: now();

auto diff = end - start;
cout<<名称<< :<< chrono :: duration< double,milli>(diff).count() ms。< }

这样我就必须使用bind或lambda,我想知道哪些会影响性能,所以我做了:

  const int TIMES = 10000; 
timeExec< TIMES>(Bind evaluation,bind(& decltype(result):: eval,& result));
timeExec&评估,[&](){
for(int i = 0; i result.eval();
}
});

结果是:

 绑定评估:0.355158 ms。
Lambda评估:0.014414 ms。

我不知道内部,但我认为lambda不能比bind更好。我可以想到的唯一可能的解释是编译器优化后面的函数评估在lambda的循环。



您会如何解释?

解决方案


我假设lambda不能比bind更好。


这是一个先入为主。



Lambdas绑定到编译器内部,因此可能会发现额外的优化机会。此外,它们旨在避免效率低下。



但是,这里可能没有编译器优化技巧。可能的罪魁祸首是bind, bind(& decltype(result):: eval,& result)的参数。您正在传递指针到成员函数(PTMF)和对象。与lambda类型不同,PTMF不捕获什么函数实际被调用;它只包含函数签名(参数和返回类型)。



如果你重命名成员,那么这个慢循环正在使用间接分支函数调用,因为编译器无法通过常量传播来解析函数指针。 eval() operator()()并除去 bind 显式对象基本上表现得像lambda,性能差异应该消失。


I wanted to time a few functions' execution and I've written myself a helper:

using namespace std;
template<int N = 1, class Fun, class... Args>
void timeExec(string name, Fun fun, Args... args) {

    auto start = chrono::steady_clock::now();

    for(int i = 0; i < N; ++i) {
        fun(args...);
    }

    auto end = chrono::steady_clock::now();

    auto diff = end - start;
    cout << name << ": "<< chrono::duration<double, milli>(diff).count() << " ms. << endl;
}

I figured that for timing member functions this way I'd have to use bind or lambda and I wanted to see which would impact the performance less, so I did:

const int TIMES = 10000;
timeExec<TIMES>("Bind evaluation", bind(&decltype(result)::eval, &result));
timeExec<1>("Lambda evaluation", [&]() {
    for(int i = 0; i < TIMES; ++i) {
        result.eval();
    }
});

The results are:

Bind evaluation: 0.355158 ms.
Lambda evaluation: 0.014414 ms.

I don't know the internals, but I assume that lambda cannot be that better than bind. The only plausible explanation I can think of is the compiler optimizing-out subsequent function evaluations in the lambda's loop.

How would you explain it?

解决方案

I assume that lambda cannot be that better than bind.

That's quite a preconception.

Lambdas are tied into the compiler internals, so extra optimization opportunities may be found. Moreover, they're designed to avoid inefficiency.

However, there are probably no compiler optimization tricks happening here. The likely culprit is the argument to bind, bind(&decltype(result)::eval, &result). You are passing a pointer-to-member-function (PTMF) and an object. Unlike the lambda type, the PTMF does not capture what function actually gets called; it only contains the function signature (parameter and return types). The slow loop is using an indirect branch function call, because the compiler failed to resolve the function pointer through constant propagation.

If you rename the member eval() to operator () () and get rid of bind, then the explicit object will essentially behave like the lambda and the performance difference should disappear.

这篇关于std :: bind与lambda性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆