c++ - std::bind 与 lambda 性能

标签 c++ caching c++11 lambda bind

我想为一些函数的执行计时,我给自己写了一个助手:

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;
}

我认为以这种方式为成员函数计时,我必须使用 bind 或 lambda,我想看看哪个对性能的影响较小,所以我这样做了:

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();
    }
});

结果是:

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

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

你会怎么解释?

最佳答案

I assume that lambda cannot be that better than bind.

这是一个相当成见。

Lambda 被绑定(bind)到编译器内部,因此可以找到额外的优化机会。此外,它们旨在避免效率低下。

但是,这里可能没有发生编译器优化技巧。可能的罪魁祸首是 bind 的参数 bind(&decltype(result)::eval, &result)。您正在传递一个指向成员函数 (PTMF) 的指针和一个对象。与 lambda 类型不同,PTMF 不捕获实际调用的函数;它只包含函数签名(参数和返回类型)。慢循环使用的是间接分支函数调用,因为编译器无法通过常量传播解析函数指针。

如果将成员 eval() 重命名为 operator () () 并去掉 bind,那么显式对象本质上将表现得像 lambda,性能差异应该消失。

关于c++ - std::bind 与 lambda 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24852764/

相关文章:

android - 如何为 volley 实现 JSON 流概念以避免 OutOfMemory 错误?

c++ - 如何将 std::system_error 与 GetLastError 一起使用?

c++ - 复制 vs std::move 用于整数

C++ 不会告诉您动态数组的大小。但为什么?

c++ - 我可以为 C++11 std::tuple 预分配一 block 内存吗?

php - Doctrine 2 结果缓存

PHP APC 缓存,开箱即用吗?

c++ - 您如何称呼 2 个 .c 文件之间的这种关系?

c++ - 为什么在重载 = 运算符时通过引用返回?

c++ - 警告 : non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]