Iterator fusion
- Rust kursu
- Uzman
- Ders 15/46
- 4 dk
Iterator fusion ile optimizasyon yapmayı öğrenirsin.
Iterator fusion
Zincirlenmiş bağdaştırıcılar ayrı ayrı geçişler yapmaz: her eleman tüm zinciri tek seferde geçer. Derleyici satır içi alma ile zinciri tek bir döngüye "kaynaştırır". Bu, sırayı gözlemleyince açıkça görülür:
let kayit = RefCell::new(Vec::new());
let _ = (1..=3)
.map(|x| { kayit.borrow_mut().push(format!("m{x}")); x * 2 })
.filter(|x| { kayit.borrow_mut().push(format!("f{x}")); *x > 2 })
.count();
// m1 f2 m2 f4 m3 f6 — önce tüm map'ler değil, eleman elemanAra koleksiyon oluşmadığı için bellek kullanımı da sabittir.
collect araları
Zincirin ortasına collect koymak kaynaşmayı bozar: tüm elemanlar bir vektöre yazılır, sonra yeniden okunur. Yalnızca gerçekten gerektiğinde (sıralama, birden çok geçiş) ara koleksiyon kullan:
// gereksiz ara vektör
let ara: Vec<_> = v.iter().map(|x| x * 2).collect();
let t: i32 = ara.iter().filter(|x| **x > 2).sum();
// kaynaşmış
let t: i32 = v.iter().map(|x| x * 2).filter(|x| *x > 2).sum();Uygulama Kaynaşmayı gözle
Yukarıdaki örneği yaz: RefCell<Vec<String>> günlüğüne map içinde mX, filter içinde fX ekle; zinciri count() ile tüket. Günlüğü boşlukla birleştirip yazdır.
Başlangıç kodu
use std::cell::RefCell;
fn main() {
// buraya yaz
}Örnek çözüm
use std::cell::RefCell;
fn main() {
let kayit = RefCell::new(Vec::new());
let _adet = (1..=3)
.map(|x| {
kayit.borrow_mut().push(format!("m{x}"));
x * 2
})
.filter(|x| {
kayit.borrow_mut().push(format!("f{x}"));
*x > 2
})
.count();
println!("{}", kayit.borrow().join(" "));
}Beklenen çıktı
m1 f2 m2 f4 m3 f6
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Neden günlük için <code>RefCell</code> gerekti?
- Gerekmezdi
- Thread'ler için
- İki closure aynı vektörü değiştirmek istiyor; iki &mut aynı anda yakalanamaz Doğru cevap
- Hız için
Açıklama: Her closure yalnızca &RefCell yakalar; değiştirme çalışma anında, kısa ödünçlerle yapılır.
2 Paylaşılan günlük
let kayit = ____::new(Vec::new());
// iki closure da kayit.borrow_mut() ile yazar
let kayit = RefCell::new(Vec::new());
// iki closure da kayit.borrow_mut() ile yazar
Açıklama: RefCell iki closure'ın aynı vektörü sırayla değiştirmesine izin verir.
3 Zincir ve geçiş sayısı
| Kavram | Anlamı |
|---|---|
map + filter + sum |
1 geçiş |
map + collect + filter + sum |
2 geçiş |
sort gerektiren iş |
Ara koleksiyon şart |
take(2) |
Erken durur |