Ruby performansını artırma: C'yi Ruby ile yeniden yazmak
Ruby'nin performans karşılaştırması
- Yakın tarihli bir dil karşılaştırma deposunda Ruby, R ve Python'dan daha hızlı olsa da üçüncü en yavaş dil olarak değerlendirildi.
- Benchmark'lar "Loops" ve "Fibonacci" olmak üzere iki bölümden oluşuyor; bunlar sırasıyla döngü ve koşul ifadeleri ile fonksiyon çağrısı ek yükünü ve özyineleme performansını öne çıkarıyor.
Ruby ile Node.js performans karşılaştırması
- M3 MacBook Pro'da Ruby 3.3.6, döngü örneğinde 28 saniye, fibonacci örneğinde ise 12 saniye sürüyor.
- Node.js ise her iki örnekte de yaklaşık 1 saniye sürüyor.
- M2 MacBook Air'de Ruby'nin performansı daha da kötüleşiyor.
Benchmark'ların anlamı
- Bu tür benchmark'lar pratikte çok büyük bir anlam taşımayabilir.
- Python en yavaş dil olarak değerlendirildi, ancak GitHub'da en çok kullanılan dil.
- Programlama dilleri verimli olmalı, ancak bir dilin kullanışlılığı ve üretkenliği performanstan daha önemlidir.
YJIT'nin uygulanması
- YJIT uygulandığında fibonacci performansı büyük ölçüde iyileşiyor.
- Döngü örneğinde ise performans artışı sınırlı kalıyor.
Ruby kodu optimizasyonu
Range#each C ile yazıldığı için YJIT tarafından optimize edilemiyor.
Integer#times, Ruby 3.3'te C'den Ruby'ye dönüştürüldü ve bu sayede YJIT optimizasyonu mümkün oldu.
Array#each, Ruby 3.4'te C'den Ruby'ye dönüştürüldü.
Integer#times optimizasyonu
Integer#succ, i += 1 ifadesinden daha hızlı çalışıyor.
- YJIT,
Integer#times'ı optimize ederek performansı önemli ölçüde artırıyor.
Array#each optimizasyonu
Array#each, Ruby 3.4'te C'den Ruby'ye dönüştürüldü ve YJIT optimizasyonu mümkün hale geldi.
Primitive modülü kullanılarak C kodu Ruby içinde değerlendiriliyor.
Ruby Microbench deposu
- Çeşitli Ruby sürümleri ve YJIT kullanılarak benchmark'lar çalıştırılıyor.
- Ruby 3.4 YJIT ile performans belirgin biçimde iyileşiyor.
range#each optimizasyonu
Range sınıfını saf Ruby ile uygulayarak performans artırılabilir.
YJIT standart kütüphanesi
- YJIT ekibi, C kodunu Ruby ile değiştirerek performansı artırıyor.
with_yjit bloğu kullanılarak YJIT etkin olduğunda Ruby implementasyonu kullanılıyor.
YJIT optimizasyonunu inceleme
- YJIT, Ruby VM bytecode'unu makine koduna çevirerek performansı optimize ediyor.
Integer#succ için üretilen makine kodu analiz edilerek YJIT'nin optimizasyon süreci anlaşılabiliyor.
1 yorum
Hacker News yorumları
Döngü örneği 1 milyar kez tekrar ediyor ve iç içe döngüler kullanıyor. Bu benchmark'ın sürenin %99'undan fazlasını ilk iki satırda harcayacağı tahmin ediliyor
uderleme zamanında bilinmese bile iç döngü birkaç komutla değiştirilebilirRuby'nin gelecekteki sürümlerine değiniliyor; Ruby 3.4.0'ın bu Noel'de, Ruby 3.5.0'ın ise gelecek Noel'de çıkması planlanıyor
Ruby'ye duyulan sevgi hâlâ sürüyor. Matz'a teşekkür ediliyor
Integer#succiçin performans iyileştirme PR'ı 2024'ün başında yapılmış ve bu sayede nedenInteger#succkullanıldığı anlaşılmışInteger#succkullanılıyor ve yorumlayıcıdaopt_succ (i = i.succ)ifadesiputobject 1; opt_plus (i += 1)ifadesinden daha hızlı işleniyor#succsık kullanılıyor; UUID kütüphanesinin#bytesmetodunda bunu iki kez kullanarak kod okunurken "bit slicing modu" korunuyorTruffleRuby ile ilgili deneyimler paylaşılıyor; TruffleRuby'nin Node.js'ten daha hızlı olduğu ve Bun ya da Golang'a yaklaştığı belirtiliyor
Ruby çok hızlandı ve TruffleRuby daha da etkileyici
YJIT'in Rust ile yazıldığı bilinmiyormuş
Python benchmark'ta en yavaş dildi, ancak Ekim 2024 itibarıyla GitHub'da en çok kullanılan dil
Daha fazla dili içeren eski bir dil karşılaştırma deposu var
Advent of Code çözümlerinde büyük değişikliklere yol açmış ve şaşırtıcı derecede benzer görünüyor