Performance Tuning: Rust Kodunu Daha Hızlı Hale Getirme

  • Konbuyu başlatan Konbuyu başlatan irfo
  • Başlangıç tarihi Başlangıç tarihi

irfo

Moderatör
Katılım
7 Ocak 2026
Mesajlar
290
Tepkime puanı
2
Puanları
18
Rust'ın "sıfır maliyetli soyutlamaları" (zero-cost abstractions) size hızlı bir temel sunar, ancak en iyi performansı elde etmek için dilin belleği ve işlemciyi nasıl kullandığını anlamanız gerekir. Rust kodunuzda darboğazları gidermek ve performansı zirveye taşımak için izlemeniz gereken stratejiler şunlardır:


1. İlk Kural:​

Yeni başlayanların yaptığı en yaygın hata, kodu sadece cargo run ile çalıştırmaktır. Standart derleme, hata ayıklama (debug) sembollerini içerir ve hiçbir optimizasyon yapmaz.

  • Debug: Hızlı derleme, yavaş çalışma.
  • Release: Yavaş derleme (optimizasyonlar nedeniyle), çok hızlı çalışma.

2. Heap Tahsislerini (Allocations) Azaltın​

Rust'ta bellek güvenlidir ama bellekte yer ayırmak (allocation) maliyetlidir. String::new() veya vec![] gibi ifadeler Heap (Öbek) üzerinde yer ayırır.

  • Reuse (Yeniden Kullanım): Bir döngü içinde sürekli yeni vektör oluşturmak yerine, mevcut olanı .clear() ile temizleyip tekrar kullanın.
  • Capacity (Kapasite): Veri boyutunu yaklaşık olarak biliyorsanız, with_capacity kullanarak belleğin sürekli yeniden boyutlandırılmasını (reallocation) önleyin.
Kod:
// Yavaş: Her seferinde yeni yer ayırırfor i in 0..1000 {let mut v = Vec::new();v.push(i);}

// Hızlı: Tek seferde yer ayırır ve yeniden kullanırlet mut v = Vec::with_capacity(1000);for i in 0..1000 {v.push(i);}


3. Akıllı İşaretçilerin (Smart Pointers) Maliyeti​

Box, Rc ve Arc gibi yapılar esneklik sağlar ancak dolaylı erişim (indirection) nedeniyle bir miktar maliyet getirir.

  • Dereference: Mümkünse veriyi bir akıllı işaretçi içinde değil, doğrudan referans (&T) olarak geçirin.
  • Arc vs Rc: Thread güvenliği gerekmiyorsa Arc yerine Rc kullanın; Arc içindeki atomik işlemler daha yavaştır.

4. Iterators (Yineleyiciler) ve Döngüler​

Rust'ta for döngüleri yerine Iterators (map, filter, fold) kullanmak genellikle daha hızlıdır. Çünkü:

  1. Bounds Check Elimination: Derleyici, yineleyici kullanırken dizinin sınırlarını aşmayacağınızı bilir ve her adımda yapılan güvenlik kontrollerini (bounds checking) kaldırır.
  2. Internal Iteration: Derleyici, döngüyü işlemciye en uygun şekilde optimize edebilir.

5. Veri Yapılarını Doğru Seçin​

  • BTreeMap vs HashMap: Çok fazla veri ekleme/çıkarma yapıyorsanız HashMap hızlıdır. Ancak verileriniz sıralı olmalıysa veya küçükse BTreeMap işlemci önbelleğiyle (L1/L2 cache) daha uyumlu çalışabilir.
  • SmallVec: Eğer listeniz genellikle 3-4 elemanlı ama bazen büyüyorsa, küçük durumlar için Stack'i, büyük durumlar için Heap'i kullanan smallvec kütüphanesini tercih edin.

6. Profiling: Nerede Yavaşladığınızı Bulun​

Tahmin yürütmeyin, ölçün. Rust kodunuzdaki darboğazları bulmak için şu araçları kullanın:

  • cargo-flamegraph: Kodunuzun hangi fonksiyonlarda daha fazla zaman harcadığını görselleştirir.
  • criterion: Rust için endüstri standardı olan istatistiksel benchmarking kütüphanesidir.

7. LTO (Link Time Optimization)​

Büyük projelerde, farklı modüller arasındaki optimizasyonu artırmak için Cargo.toml dosyanıza LTO'yu ekleyebilirsiniz. Bu, tüm binary genelinde bir optimizasyon yapar.

Kod:
[profile.release]lto = true          # Link Time Optimization'ı açarcodegen-units = 1   # Derleyiciyi daha derin analiz yapmaya zorlarpanic = 'abort'     # Hata durumunda yığın temizleme yapmaz, binary küçülür ve hızlanır


Özet​

Performans iyileştirme bir dengedir. Önce kodunuzun temiz ve doğru olduğundan emin olun, ardından Criterion ile ölçüm yaparak en çok zaman harcanan %5'lik kısmı optimize edin. Rust, size bu %5'lik kısımda en düşük seviyeli donanım optimizasyonlarını yapma gücünü verecektir.
 
Geri
Üst