Saya menjalankan benchmark membandingkan fungsi rekursif vs fungsi lambda rekursif menggunakan std::function<>
metode penangkapan. Dengan optimalisasi penuh diaktifkan pada dentang versi 4.1, versi lambda berjalan lebih lambat.
#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);
}
Menghasilkan hasil:
Duration: 0 // regular function
Duration: 4027 // lambda function
(Catatan: Saya juga mengonfirmasi dengan versi yang mengambil input dari cin, sehingga menghilangkan evaluasi waktu kompilasi)
Dentang juga menghasilkan peringatan kompiler:
main.cc:10:29: warning: variable 'sum2' is uninitialized when used within its own initialization [-Wuninitialized]
Yang diharapkan, dan aman, tetapi harus diperhatikan.
Sangat menyenangkan memiliki solusi di sabuk alat kami, tetapi saya pikir bahasanya akan membutuhkan cara yang lebih baik untuk menangani kasus ini jika kinerja harus sebanding dengan metode saat ini.
catatan:
Seperti yang ditunjukkan oleh komentator, sepertinya versi terbaru VC ++ telah menemukan cara untuk mengoptimalkan ini ke titik kinerja yang sama. Mungkin kita tidak membutuhkan cara yang lebih baik untuk menangani ini (kecuali untuk gula sintaksis).
Juga, seperti beberapa pos SO lainnya telah diuraikan dalam beberapa minggu terakhir, kinerja std::function<>
itu sendiri mungkin menjadi penyebab fungsi pelambatan vs panggilan secara langsung, setidaknya ketika tangkapan lambda terlalu besar untuk masuk ke dalam beberapa std::function
penggunaan ruang perpustakaan yang dioptimalkan untuk fungsi-fungsi kecil (Saya kira agak seperti berbagai optimasi string pendek?).