Saya telah mencoba ekspresi const yang dievaluasi pada waktu kompilasi. Tapi saya bermain dengan contoh yang tampak sangat cepat ketika dieksekusi pada waktu kompilasi.
#include<iostream>
constexpr long int fib(int n) {
return (n <= 1)? n : fib(n-1) + fib(n-2);
}
int main () {
long int res = fib(45);
std::cout << res;
return 0;
}
Ketika saya menjalankan kode ini, dibutuhkan sekitar 7 detik untuk menjalankannya. Sejauh ini bagus. Tapi ketika saya mengubah long int res = fib(45)
untuk const long int res = fib(45)
dibutuhkan bahkan satu detik. Untuk pemahaman saya itu dievaluasi pada waktu kompilasi.
Tetapi kompilasi membutuhkan waktu sekitar 0,3 detik
Bagaimana kompilator dapat mengevaluasi hal ini dengan sangat cepat, tetapi pada saat runtime dibutuhkan waktu lebih lama? Saya menggunakan gcc 5.4.0.
fib
. Implementasi angka-angka fibonacci yang Anda miliki di atas sangat lambat. Coba caching nilai-nilai fungsi dalam kode runtime dan itu akan jauh lebih cepat.Jawaban:
Compiler melakukan cache nilai yang lebih kecil dan tidak perlu menghitung ulang sebanyak versi runtime.
(Pengoptimal sangat baik dan menghasilkan banyak kode termasuk tipu daya dengan kasus khusus yang tidak dapat dipahami oleh saya; rekursi naif 2 ^ 45 akan memakan waktu berjam-jam.)
Jika Anda juga menyimpan nilai sebelumnya:
versi runtime jauh lebih cepat daripada kompiler.
sumber
fib
Fungsi yang diberikan tidak memiliki efek samping (referensi tidak ada variabel eksternal, output tergantung pada input saja), dengan pengoptimal yang pintar banyak yang dapat dilakukan.Anda mungkin menemukan menarik dengan 5,4 fungsi tidak sepenuhnya dihilangkan, Anda perlu setidaknya 6,1 untuk itu.
Saya tidak berpikir ada caching yang terjadi. Saya yakin pengoptimal cukup pintar untuk membuktikan hubungan antara
fib(n - 2)
danfib(n-1)
dan menghindari panggilan kedua sepenuhnya. Ini adalah keluaran GCC 5.4 (diperoleh dari godbolt) tanpaconstexpr
dan -O2:Saya harus mengakui bahwa saya tidak mengerti keluaran dengan -O3 - kode yang dihasilkan sangat kompleks, dengan banyak akses memori dan pointer arithmetics dan sangat mungkin ada beberapa caching (memoisasi) yang dilakukan dengan pengaturan tersebut.
sumber