Menghindari biaya panggilan fungsi hanya setengah dari cerita.
melakukan:
- gunakan
inline
sebagai ganti#define
- fungsi yang sangat kecil adalah kandidat yang baik untuk
inline
: kode yang lebih cepat dan executable yang lebih kecil (lebih banyak peluang untuk tetap dalam cache kode)
- fungsinya kecil dan disebut sangat sering
jangan:
- fungsi besar: mengarah ke executable lebih besar, yang secara signifikan merusak kinerja terlepas dari eksekusi lebih cepat yang dihasilkan dari panggilan overhead
- fungsi sebaris yang terikat I / O
- fungsi ini jarang digunakan
- konstruktor dan destruktor: bahkan ketika kosong, kompilator menghasilkan kode untuk mereka
- melanggar kompatibilitas biner saat mengembangkan perpustakaan:
- sebaris fungsi yang ada
- mengubah fungsi inline atau membuat fungsi inline non-inline: versi sebelumnya dari perpustakaan memanggil implementasi lama
saat mengembangkan perpustakaan, untuk membuat kelas dapat dikembangkan di masa mendatang Anda harus:
- tambahkan destruktor virtual non-inline bahkan jika badan kosong
- buat semua konstruktor menjadi non-inline
- tulis implementasi non-inline dari copy constructor dan operator penugasan kecuali kelas tidak dapat disalin oleh nilai
Ingatlah bahwa inline
kata kunci adalah petunjuk bagi kompiler: kompiler dapat memutuskan untuk tidak menyelaraskan suatu fungsi dan dapat memutuskan untuk menyelaraskan fungsi yang tidak ditandai inline
sejak awal. Saya biasanya menghindari fungsi menandaiinline
(selain mungkin ketika menulis fungsi yang sangat kecil).
Tentang kinerja, pendekatan bijak adalah (seperti biasa) untuk membuat profil aplikasi, kemudian pada akhirnya inline
seperangkat fungsi yang mewakili hambatan.
Referensi:
EDIT: Bjarne Stroustrup, Bahasa Pemrograman C ++:
Suatu fungsi dapat didefinisikan sebagai inline
. Sebagai contoh:
inline int fac(int n)
{
return (n < 2) ? 1 : n * fac(n-1);
}
The inline
specifier adalah petunjuk untuk compiler yang harus berusaha untuk menghasilkan kode untuk panggilan dari fac()
inline daripada meletakkan kode untuk fungsi sekali dan kemudian memanggil melalui mekanisme pemanggilan fungsi biasa. Kompiler yang pintar dapat menghasilkan konstanta 720
untuk panggilan fac(6)
. Kemungkinan fungsi inline yang saling rekursif, fungsi inline yang berulang atau tidak bergantung pada input, dll., Membuat tidak mungkin untuk memastikan bahwa setiap panggilan inline
fungsi sebenarnya digarisbawahi. Tingkat kepintaran dari sebuah kompiler tidak dapat diundangkan, sehingga satu kompiler dapat menghasilkan 720
, yang lain 6 * fac(5)
, dan yang lainnya panggilan yang tidak digariskan fac(6)
.
Untuk memungkinkan inlining jika tidak ada kompilasi yang luar biasa pintar dan fasilitas penghubung, definisi - dan bukan hanya deklarasi - dari fungsi sebaris harus dalam ruang lingkup (§9.2). Sebuah inline
especifier tidak mempengaruhi semantik fungsi. Secara khusus, fungsi inline masih memiliki alamat unik dan demikian juga static
variabel (§7.1.2) dari fungsi inline.
EDIT2: ISO-IEC 14882-1998, 7.1.2 Penentu fungsi
Deklarasi fungsi (8.3.5, 9.3, 11.4) dengan inline
specifier menyatakan fungsi inline. Penspesifikasi sebaris menunjukkan pada implementasi bahwa substitusi sebaris dari fungsi tubuh pada titik panggilan lebih disukai daripada mekanisme panggilan fungsi yang biasa. Implementasi tidak diperlukan untuk melakukan penggantian inline ini di titik panggilan; namun, bahkan jika penggantian inline ini dihilangkan, aturan lain untuk fungsi inline yang didefinisikan oleh 7.1.2 tetap harus dihormati.
inline
adalah untuk pendatang baru C ++ apaCFLAGS
yang menjadi pendatang baru Gentoo: tidak, kompilasi dengan-O3 -funroll-loops -finline-functions
tidak akan membuat Pentium lama Anda terbang;)