Rust
Profilli optimizasyon
flamegraph ile performans iyileştirmesi yaparsın.
Bitirme görevi: profilli optimizasyon
Son görev, optimizasyonun doğru sırasını uygular: ölç → darboğazı bul → algoritmayı düzelt → yeniden ölç. Örnek bir sıcak fonksiyon: özyinelemeli Fibonacci. Flamegraph, zamanın neredeyse tamamının fib_yavas'ın kendini çağırmasında geçtiğini gösterir; çağrı sayısı üstel büyür:
fn fib_yavas(n: u32) -> u64 {
if n < 2 { n as u64 } else { fib_yavas(n - 1) + fib_yavas(n - 2) }
}
// fib_yavas(40): ~330 milyon çağrı
Hiçbir derleyici ayarı (LTO, #[inline], target-cpu) üstel bir algoritmayı kurtaramaz. Kazanç önce algoritmadan gelir.
Doğrusal sürüm
Yinelemeli sürüm her adımda yalnızca son iki değeri tutar: O(n) zaman, O(1) bellek. u64 en fazla fib(93)'ü tutabildiği için taşmayı checked_add ile güvenle bildiririz:
fn fib_hizli(n: u32) -> Option<u64> {
let (mut a, mut b) = (0u64, 1u64);
for _ in 0..n {
let c = a.checked_add(b)?;
a = b;
b = c;
}
Some(a)
}
Ardından release profilinde lto = "thin" ve codegen-units = 1 gibi ayarlar, ölçümle doğrulanırsa son yüzdeleri kazandırır.
Uygulama Hızlı Fibonacci
Yukarıdaki fib_yavas ve fib_hizli fonksiyonlarını yaz. fib_yavas(20) ile fib_hizli(20) sonuçlarının eşit olduğunu assert_eq! ile doğrula; ardından fib_yavas(20) ve fib_hizli(90) sonuçlarını boşlukla yazdır.
Örnek çözümü göster
fn fib_yavas(n: u32) -> u64 {
if n < 2 {
n as u64
} else {
fib_yavas(n - 1) + fib_yavas(n - 2)
}
}
fn fib_hizli(n: u32) -> Option<u64> {
let (mut a, mut b) = (0u64, 1u64);
for _ in 0..n {
let c = a.checked_add(b)?;
a = b;
b = c;
}
Some(a)
}
fn main() {
assert_eq!(Some(fib_yavas(20)), fib_hizli(20));
println!("{} {}", fib_yavas(20), fib_hizli(90).unwrap());
}
Kendini test et
-
Algoritmayı düzelttikten sonra hangi adım gelir?
- Hiçbir şey
- Sonucun aynı olduğunu doğrulayıp yeniden ölçmek
- Hemen unsafe eklemek
- Profil dosyasını silmek
Cevabı göster
Sonucun aynı olduğunu doğrulayıp yeniden ölçmek — Doğruluk testi, hızlı ama yanlış bir sürümü yakalar; yeni profil bir sonraki darboğazı gösterir.
-
Taşmayı yakala
let c = a.____(b)?;
a = b;
b = c;
Cevabı göster
let c = a.checked_add(b)?;
a = b;
b = c;
-
Adım ve araç
- Ölç
- flamegraph / criterion
- Darboğaz
- En geniş plato
- Düzelt
- Daha iyi algoritma
- Doğrula
- Referansla karşılaştır
Sıradaki ders: Uzman bölüm sınavı