为什么c++ lambda在多次调用时比普通函数慢

Why C++ lambda is slower than ordinary function when called multiple times?

本文关键字:函数 调用 lambda c++ 为什么      更新时间:2023-10-16

我只是试图比较c++ 11中lambda表达式的性能,所以我做了测试-计算double值向量中的元素和。下面是实现:

#include <vector>
#include <algorithm>
#include <iostream>
#include <ctime>
#define LOG(x) { std::cout << #x << " = " << (x) << "n"; }
#define TIME(t) { std::cout << ((double)(clock() - (t)) / CLOCKS_PER_SEC) << " sn"; }
double sum(const std::vector<double>& v)
{
    double s = 0.0;
    for (auto i = v.cbegin(); i != v.cend(); ++i)
        s += *i;
    return s;
}
int main()
{
    const size_t MAX = 1; // number of tests
    const size_t SIZE = 100000000; // length of the vector
    std::vector<double> v(SIZE, 1.0);
    double out;
    clock_t clk;
    std::cout << "iteratorn";
    clk = clock();
    out = 0.0;
    for (size_t i = 0; i < MAX; ++i)
        out += sum(v);
    TIME(clk)
    LOG(out)
    std::cout << "nlambdan";
    clk = clock();
    out = 0.0;
    for (size_t i = 0; i < MAX; ++i)
        std::for_each(v.cbegin(), v.cend(), [&](double d) { out += d; });
    TIME(clk)
    LOG(out)
    return 0;
}

下面是这个程序的结果(在VS2010 SP1中编译,在Release模式下):

<>之前迭代器0.32秒Out = 1e+008λ0.326秒Out = 1e+008之前

可以看出,在性能上几乎没有差别。但是,如果我将MAX的值设为10(这意味着将执行10次而不是1次求和),结果就不同了:

<>之前迭代器0.287秒Out = 1e+009λ2.84秒Out = 1e+009之前

测试lambda表达式花费了大约10倍的时间。为什么?我认为这可能是由于这样的事实,即在每次迭代新的lambda被创建,但当我尝试这个:

out = 0.0;
auto f = [&](double d) { out += d; };
for (size_t i = 0; i < MAX; ++i)
    std::for_each(v.cbegin(), v.cend(), f);

结果没有改变。有人能给我解释一下这种行为吗?

事实证明,这不是lambda表达式的问题,只是编译器通过缓存sum()函数的结果优化了第一种情况下的外部循环。

将第一个大小写改为如下形式:

out = 0.0;
for (size_t i = 0; i < MAX; ++i)
{
    out += sum(v);
    v[i] = 1.0; // this adds O(1) time and prevents caching
}

在这两种情况下,时间大致相等,lambda是首选。