Я быстро написал «простой», но, надеюсь, не слишком глупый тест, чтобы проверить, не пытается ли метод всегда пытаться не назначать лямбду для std::function
(потому что она медленнее? -> хотя бы для одной виртуальной функции (не уверен)) имеет смысл.
#include <iostream>
#include <functional>
#include <chrono>
typedef std::chrono::high_resolution_clock::time_point TimeVar;
#define duration(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()
template<typename T, typename F>
auto time(T t, F &&rF)
{
std::cout << t << "\t";
TimeVar t1=timeNow();
int a = rand()%10;
for(int i=0;i<10000000;i++)
{
a = rF(a);
}
auto count = duration(timeNow()-t1);
std::cout << "a: " << a << " time: " << count << " ns " << std::endl;
return count;
}
template<typename T>
auto timeN(T t)
{
std::cout << t << "\t";
TimeVar t1=timeNow();
int a = rand()%10;
for(int i=0;i<10000000;i++)
{
a = a + rand()%10;
}
auto count = duration(timeNow()-t1);
std::cout << "a: " << a << " time: " << count << " ns " << std::endl;
return count;
}
int main()
{
auto c1 = time("lambda: ", [](int a) { return a + rand()%10; });
auto c2 = time("std::function: ", std::function<int(int)>{[](int a) { return a + rand()%10; }});
auto c3 = timeN("baseline: ");
std::cout << std::endl;
std::cout << "lambda: \t" << (float)c1/c3 << " x slower then baseline" << std::endl;
std::cout << "std::function: \t" << (float)c2/c3 << " x slower then baseline" << std::endl;
std::cout << "std::function: \t" << (float)c2/c1 << " x slower then lambda" << std::endl;
}
Live
Вывод:
lambda: a: 45011713 time: 182743890 ns
std::function: a: 45000320 time: 161290160 ns
baseline: a: 45004251 time: 134701347 ns
lambda: 1.35666 x slower then baseline
std::function: 1.19739 x slower then baseline
std::function: 0.882602 x slower then lambda
Это озадачивает меня, поскольку лямбда медленнее, чем std ::функция.Зачем?Я имею в виду, что тип лямбды генерируется компилятором, и я предположил, что он может оптимизировать намного больше, чем непрозрачный тип std :: function.(если вы компилируете с помощью clang, вы получите противоположный результат).Также возникает вопрос, почему функция std :: работает так быстро, если ее непрозрачный тип ...?Является ли назначение особенным для лямбд и оптимизировано?