Misalnya saya punya kode berikut:
auto z = [](int x) -> int {
if (x > 0) {
switch (x) {
case 2: return 5;
case 3: return 6;
default: return 1;
}
}
return 0;
};
Dan kemudian saya menyebutnya beberapa kali. Dalam kode asm saya melihat panggilan eksternal dengan lambda .... sesuatu ... Ini menjadi tidak mudah dibaca dan saya pikir itu juga dapat menyebabkan kinerja. Jadi mungkin saya menang dalam meta-pemrograman tetapi apakah saya kalah dalam asm debugging dan kinerja? Haruskah saya menghindari fitur bahasa modern, makro dan aspek pemrograman meta lainnya untuk memastikan kinerja dan kesederhanaan debugging?
if
benar-benar berlebihan dalam kode contoh, dan sementara compiler mungkin akan menangkap bahwa tidak ada alasan untuk menggoda prediksi cabang buruk.Jawaban:
Tidak , tidak ketika Anda menulis kode Anda pertama kali dan tidak menderita masalah kinerja nyata yang dapat diukur. Untuk sebagian besar tugas, ini adalah kasus standar. Berpikir terlalu dini tentang pengoptimalan disebut "pengoptimalan prematur", dan ada alasan bagus mengapa D. Knuth menyebut itu "akar dari semua kejahatan" .
Ya , ketika Anda mengukur hambatan kinerja nyata yang dapat dibuktikan, dan Anda mengidentifikasi bahwa konstruksi lambda spesifik sebagai penyebab utama. Dalam hal ini, mungkin ide yang baik untuk mengingat "hukum abstraksi bocor" karya Joel Spolsky dan memikirkan apa yang mungkin terjadi pada level asm. Namun berhati-hatilah, Anda mungkin akan heran betapa kecilnya peningkatan kinerja ketika Anda mengganti sebuah konstruksi lambda dengan sebuah konstruksi bahasa yang "tidak begitu modern" (setidaknya, ketika menggunakan kompiler C ++ yang layak).
sumber
Pilihan antara lambda dan kelas functor adalah pertukaran.
Keuntungan dari lambda sebagian besar sintaksis, dengan meminimalkan jumlah boilerplate dan memungkinkan kode terkait secara konseptual ditulis inline, di dalam fungsi yang akan menggunakannya (segera atau lambat).
Dari segi kinerja, ini tidak lebih buruk dari kelas functor , yang merupakan C ++ struct atau kelas yang berisi "metode" tunggal. Bahkan, kompiler memperlakukan lambda tidak berbeda dengan kelas functor yang dihasilkan kompiler di belakang layar.
Dalam contoh kode Anda, kinerja-bijaksana itu tidak berbeda dari panggilan fungsi, karena kelas functor kebetulan tidak memiliki keadaan (karena memiliki klausa tangkap kosong), sehingga tidak memerlukan alokasi, konstruktor atau penghancuran.
Mendebug kode C ++ non-sepele menggunakan disassembler selalu menjadi tugas yang sulit. Ini benar dengan atau tanpa menggunakan lambda. Ini disebabkan oleh optimisasi kode canggih oleh kompiler C ++ yang menghasilkan penataan ulang, interleaving, dan penghilangan kode mati.
Aspek penyusunan nama agak tidak menyenangkan, dan dukungan debugger untuk lambda masih dalam masa pertumbuhan . Hanya dapat diharapkan bahwa dukungan debugger akan meningkat seiring waktu.
Saat ini, cara terbaik untuk men-debug kode lambda adalah dengan menggunakan debugger yang mendukung pengaturan breakpoint pada tingkat kode sumber, yaitu dengan menentukan nama file sumber dan nomor baris.
sumber
Untuk menambah jawaban dengan @DocBrown, ingat bahwa hari ini CPU murah tetapi tenaga kerja mahal.
Dalam keseluruhan biaya suatu program, perangkat keras biasanya sepele dibandingkan dengan biaya pemeliharaan, yang sejauh ini merupakan bagian paling mahal dari proyek tipikal (bahkan lebih dari pengembangannya).
Oleh karena itu, kode Anda perlu mengoptimalkan pemeliharaan di atas segalanya, kecuali ketika kinerjanya sangat penting (dan itupun pemeliharaan perlu dipertimbangkan).
sumber