Почему лямбда-выражение C ++ при многократном вызове медленнее, чем обычная функция?

Я только что попытался сравнить производительность лямбда-выражений в C ++ 11, поэтому я провел тест - вычислил сумму элементов в векторе двойных значений. Вот реализация:

#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) << " s\n"; }

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 << "iterator\n";

    clk = clock();
    out = 0.0;
    for (size_t i = 0; i < MAX; ++i)
        out += sum(v);
    TIME(clk)
    LOG(out)

    std::cout << "\nlambda\n";

    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):

iterator
0.32 s
out = 1e+008

lambda
0.326 s
out = 1e+008

Как видим, разницы в производительности практически нет. Однако, если я даю 10 в качестве значения MAX (это означает, что суммирование будет выполняться 10 раз вместо одного), результаты будут отличаться:

iterator
0.287 s
out = 1e+009

lambda
2.84 s
out = 1e+009

Проверка лямбда-выражения заняла примерно в 10 раз больше времени. Почему? Я думал, что это может быть вызвано тем фактом, что на каждой итерации создается новая лямбда, но когда я попробовал это:

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

результаты не изменились. Может ли кто-нибудь объяснить мне такое поведение?

26
задан Flexo 28 December 2011 в 00:19
поделиться