Ho appena provato a confrontare le prestazioni delle espressioni lambda in C++ 11, quindi ho eseguito la somma di elementi di prova di calcolo in un vettore di valori double
. Ecco l'attuazione:Perché C + + lambda è più lento della funzione normale quando viene chiamato più volte?
#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;
}
Ecco il risultato di questo programma (compilato in VS2010 SP1, in modalità di rilascio):
iterator 0.32 s out = 1e+008 lambda 0.326 s out = 1e+008
Come si può vedere, non c'è praticamente alcuna differenza in termini di prestazioni. Tuttavia, se do 10 come valore di MAX
(significa somma verrà eseguita 10 volte invece di uno), risultati differiscono:
iterator 0.287 s out = 1e+009 lambda 2.84 s out = 1e+009
del test per l'espressione lambda voluti circa 10 volte più tempo. Perché? Ho pensato che potrebbe essere causato dal fatto, che su ogni iterazione nuova lambda si crea, ma stuzzicare ho provato questo:
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);
i risultati non erano cambiate. Qualcuno potrebbe spiegarmi questo comportamento?
Questo è molto intrigante! Potresti provare a usare lambda in un ciclo scritto a mano invece di 'foreach'? – dasblinkenlight
g ++ 4.6.2 su linux fornisce tempi di esecuzione esattamente identici (0.13 - 0.12 s sul mio computer) – Cubbi
Non più mistero, controlla la mia modifica. Il mio errore, ma lo trovo piuttosto interessante. :) – Archie