Dalam bukunya The C++ Standard Library (Second Edition)
Nicolai Josuttis menyatakan bahwa lambdas dapat lebih dioptimalkan oleh kompiler daripada fungsi biasa.
Selain itu, kompiler C ++ mengoptimalkan lambdas lebih baik daripada mereka melakukan fungsi biasa. (Halaman 213)
Mengapa demikian?
Saya pikir ketika datang ke inlining seharusnya tidak ada perbedaan lagi. Satu-satunya alasan yang dapat saya pikirkan adalah bahwa penyusun mungkin memiliki konteks lokal yang lebih baik dengan lambdas dan seperti itu dapat membuat lebih banyak asumsi dan melakukan lebih banyak optimisasi.
c++
optimization
c++11
lambda
compiler-optimization
Stephan Dollberg
sumber
sumber
Jawaban:
Alasannya adalah bahwa lambdas adalah objek fungsi sehingga meneruskannya ke templat fungsi akan instantiate fungsi baru khusus untuk objek itu. Dengan demikian kompiler dapat secara sepele menyejajarkan panggilan lambda.
Untuk fungsi, di sisi lain, peringatan lama berlaku: penunjuk fungsi dilewatkan ke templat fungsi, dan kompiler secara tradisional memiliki banyak masalah dalam mengurutkan panggilan melalui pointer fungsi. Mereka dapat secara teoritis inline, tetapi hanya jika fungsi sekitarnya inline juga.
Sebagai contoh, pertimbangkan templat fungsi berikut:
Menyebutnya dengan lambda seperti ini:
Hasil dalam Instansiasi ini (dibuat oleh kompiler):
... kompiler tahu
_some_lambda_type::operator ()
dan bisa sebaris panggilan ke itu sepele. (Dan memohon fungsimap
dengan setiap lambda lain akan membuat Instansiasi barumap
karena masing-masing lambda memiliki tipe yang berbeda.)Tetapi ketika dipanggil dengan function pointer, instantiation terlihat sebagai berikut:
... dan di sini
f
menunjuk ke alamat berbeda untuk setiap panggilanmap
dan dengan demikian kompiler tidak dapat inline panggilan kef
kecuali panggilan sekitarnyamap
juga telah diuraikan sehingga kompiler dapat menyelesaikanf
ke satu fungsi tertentu.sumber
std::sort
adalah contoh klasik dari ini menggunakan lambdas bukannya pointer fungsi di sini membawa hingga tujuh kali lipat (mungkin lebih, tapi saya tidak punya data tentang itu!) peningkatan kinerja.std::sort
, ataumap
dalam contoh saya) dan lambda itu sendiri. Lambda biasanya kecil. Fungsi lainnya - belum tentu. Kami prihatin dengan sebaris panggilan ke lambda di dalam fungsi lainnya.pred
yang definisinya terlihat, dan menggunakan gcc v5.3,std::find_if(b, e, pred)
tidak sebarispred
, tetapistd::find_if(b, e, [](int x){return pred(x);})
tidak. Dentang berhasil inline keduanya, tetapi tidak menghasilkan kode secepat g ++ dengan lambda.Karena ketika Anda melewatkan "fungsi" ke suatu algoritma, Anda sebenarnya menyerahkan pointer ke fungsi sehingga harus melakukan panggilan tidak langsung melalui pointer ke fungsi. Saat Anda menggunakan lambda, Anda mengirimkan objek ke instance templat yang khusus dibuat untuk jenis itu dan panggilan ke fungsi lambda adalah panggilan langsung, bukan panggilan melalui penunjuk fungsi sehingga kemungkinan besar bisa digarisbawahi.
sumber