Я провел тест сравнения рекурсивной функции против рекурсивного лямбда-функции с использованием методы std::function<>
захвата. Благодаря полной оптимизации, включенной в версии 4.1 clang, версия лямбда работала значительно медленнее.
#include <iostream>
#include <functional>
#include <chrono>
uint64_t sum1(int n) {
return (n <= 1) ? 1 : n + sum1(n - 1);
}
std::function<uint64_t(int)> sum2 = [&] (int n) {
return (n <= 1) ? 1 : n + sum2(n - 1);
};
auto const ITERATIONS = 10000;
auto const DEPTH = 100000;
template <class Func, class Input>
void benchmark(Func&& func, Input&& input) {
auto t1 = std::chrono::high_resolution_clock::now();
for (auto i = 0; i != ITERATIONS; ++i) {
func(input);
}
auto t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count();
std::cout << "Duration: " << duration << std::endl;
}
int main() {
benchmark(sum1, DEPTH);
benchmark(sum2, DEPTH);
}
Производит результаты:
Duration: 0 // regular function
Duration: 4027 // lambda function
(Примечание: я также подтвердил версию, унесшей входы от CIN, с тем, чтобы исключить компилировать оценки времени)
Clang также производит компилятор предупреждение:
main.cc:10:29: warning: variable 'sum2' is uninitialized when used within its own initialization [-Wuninitialized]
Ожидается и безопасно, но следует отметить.
Это здорово, если у вас есть решение в наших инструментальных поясах, но я думаю, что для этого случая язык будет лучше, если производительность будет сопоставима с текущими методами.
Примечание:
Как комментатор отметил, что, кажется, последняя версия VC++ нашел способ оптимизировать это с точки равной производительности. Может быть, нам не нужен лучший способ справиться с этим, в конце концов (кроме синтаксического сахара).
Кроме того, как и некоторые другие сообщения SO, изложенные в последние недели, производительность std::function<>
сама по себе может быть причиной замедления или прямой функции вызова, по крайней мере, когда захват лямбда слишком велик, чтобы вписаться в некоторое пространство, оптимизированное библиотекой std::function
использует для малых функторов (я думаю, вроде как различные короткие строковые оптимизации?).
Может ли это быть статическим против неявно динамических деклараций? –
Что там делает ключевое слово 'mutable'? –
Захват переменных с неавтоматической продолжительностью хранения не допускается. Вы должны сделать это следующим образом: https://chat.stackoverflow.com/transcript/message/39298544#39298544 –