2024'te 1 Milyon Eşzamanlı Görevi Çalıştırmak İçin Ne Kadar Belleğe İhtiyacınız Var?
(hez2010.github.io)Rust, C#, Python, Go ve Java, NodeJS gibi dillerin güncel sürümleriyle 1 milyon eşzamanlı görevi işleyen programlar çalıştırılarak bellek verimliliği karşılaştırıldı.
C# (NativeAOT) ve Rust en iyi bellek verimliliğini gösterirken, Go beklenenden yüksek bellek tüketimi nedeniyle düşük bir değerlendirme aldı. Genel olarak .NET ve Rust'ın performansı öne çıktı; Java (GraalVM) ise şaşırtıcı bir iyileşme gösterdi.
Ayrıntılı olarak Rust yaklaşık 29MB ile en az belleği kullandı; onu yaklaşık 71MB ile C# NativeAOT izledi. NodeJS 232MB, Python ise 339MB kaydetti. Go, 753MB ile nispeten yüksek bellek kullanımı göstererek hayal kırıklığı yaratan bir sonuç verdi. Java (GraalVM) ise 92MB ile büyük bir iyileşme sergiledi.
10 yorum
Benchmark koduna bakınca, Rust ve Python durumunda gerçekte concurrent task oluşturulmadığı; bunun yerine asenkron olsa da diğer task’larla paralel çalışamayan yalnızca future nesnelerinin üretildiği görülüyor gibi. Muhtemelen C# da benzer bir durumdadır. Buna karşılık Go kodu, kendi call stack’i vb. olan bir task, yani bir goroutine oluşturuyor; 1 milyon örneğinde Go’nun bellek kullanımının özellikle sıçramış görünmesinin nedeni de muhtemelen budur.
Go’yu savunmak gerekirse, Go 1 milyon çalışan fonksiyonun içinde hangi kütüphane olursa olsun çalışır. Sadece
goeklemeniz yeterlidir. Asenkron tabanlı diğer dillerde ise arada senkron şekilde biraz zaman tüketen bir kütüphane varsa, bu asenkronluğun tüm avantajlarını yiyip bitiren çılgın bir duruma dönüşür.Asenkronluğun avantajlarından %100 yararlanmak için, az da olsa zaman harcayan tüm fonksiyonları asenkrona çevirmek gerekir.
Java VirtualThread ise, hmm... bu kez şirketimizde Java VirtualThread’e güvenip ilerledik ama kütüphane uyumluluğu yüzünden sonunda normal thread’lere geri dönüp onlarca instance ayağa kaldırmak zorunda kaldığımız bir sonla karşılaştık.
Uyumluluk kısmı hakkında biraz daha bilgi verebilir misiniz? :eyes:
Spring’de sıkça söylenen, "WebFlux’u gerçekten doğru kullanmak istiyorsanız JPA yerine R2DBC ile birlikte kullanmanız gerekir; ancak o zaman gerçek değeri ortaya çıkar" şeklindeki sözün artık geçerli olmadığını söyleyebiliriz.
MS'in
msalkütüphanesininvirtualthreadüzerinde çalışmadığını duydum.Örnek olarak verdiğiniz msal kütüphanesi için de, Go tarafında thread-safe olmayan veri türleri ya da yapılar kullanan bir kütüphaneyse bunun da aynı duruma gireceğini düşünüyorum
Thread safety ile ne ilgisi var?
goroutine, zaten baştan thread safety’yi garanti eden bir sistem değil, değil mi?Bilgi için teşekkürler
Sormak istediğim bir şey var.
O zaman Go dışındaki diğer dillerde, söylediğiniz gibi senkron çalışan bir kütüphane varsa hepsi bozuluyor mu?
Yoksa diğer diller arasında da Go gibi kusursuz asenkronluğu destekleyen bir dil var mı, bunu merak ediyorum.
colorlessdiye bir ifade var. Asenkron ile senkronu ayırt etmeye gerek olmayan tek dil Go'dur. Kullanıcı açısından eşzamanlılık gerektiren programlama yapılırken zorluk ve kullanım kolaylığı bakımından Go'nun ezici bir üstünlüğü vardır.Performansı optimize edilmiş asenkron programlamadan biraz daha düşük olabilir gerçi.
Düzeltme gibi olacak ama sadece "çöküyor" ifadesiyle "mükemmel asenkron" ifadesindeki hatalı kısımlardan bahsedeceğim. Asenkron yapıda da senkron tarzı kütüphaneleri kullanmakta sorun yoktur; tabii kısa süre içinde tamamlanacağının garantisi varsa. Senkron şekilde çalışan ve çalışma süresi uzun olan bir çağrı varsa, diğer asenkron işlemlerin işlenmesi gecikir ve sorun da burada ortaya çıkar. Go'da goroutine ile yüz milyonlarca işi bile atayabildiğiniz için dilin kendisinde asenkron diye bir kavram yoktur. Kullanan kişi açısından bakınca, herhangi bir fonksiyonu sadece
goekleyerek çağırdığınızda paralel çalıştığı için inanılmaz rahattır. Bana göre gerçek anlamda mükemmel asenkron ise, dilin temeli asenkron olan JavaScript olabilir.