Soru JRuby Performansı


Ben JRuby 1.6.7 (1.9.2 modu) kullanarak çalıştırmak için arıyorum Rails 3.2.2 uygulaması var.

MRI rubisi 1.9.3'te çalışan bir örnek uygulamam var ve tipik bir istek ~ 40 ms içinde geri dönüyor: Tamamlandı 200 Tamam 36 ms (Görüntüleme: 27.5 ms | ActiveRecord: 8.2ms)

Aynı talebi kullanarak JRuby altında, sayfaya bağlı olarak 3 ila 20 kat daha yavaştır. Yukarıdaki gibi aynı işlem için ~ 180ms alır: Tamamlandı 200 Tamam, 180 ms (Görüntüleme: 153.0ms | ActiveRecord: 24.0ms)

Bu normal bir performans farkı mı? JRuby'nin MRI ile hızda kabaca eşit olduğunu okudum. Sonuçlar Mac'imde ve bir Windows sunucusunda (maalesef çalıştırılması gerekecek) duruyor. Tomcat'ın altında çalışan Warbler ile ambalajlamak da aynı derecede yavaş.

Yukarıdaki zamanlar JRuby test etmek için oluşturulan temel raylar app. Daha karmaşık uygulamada, zamanlar daha da uzakta. Bu uygulamada bazı sayfalarda çalıştırılan daha fazla ruby ​​kodu var. Görünüşe göre sayfa ne kadar fazla bağımlı olursa, gözlemlediğim performans farkı o kadar fazladır. Nerede başlayacağımı bilmediğimden, JRuby'nin ayarını yapmamıştım.

Öyleyse sorularım: bu normal mi? JRuby'yi ayarlamak için ne yapabilirim?


18
2018-04-20 19:21


Menşei




Cevaplar:


Is this a normal performance difference?
I have read that JRuby is roughly equal on speed with MRI.

Hayır, bu normal değil. JVM ısındığında, JRuby altındaki rails istekleri, hem ham yürütme hızı hem de çöp toplama açısından MRI'ya göre önemli ölçüde daha yüksek performans gösteriyor.

Uygulamanız yanlış yapılandırılmış gibi görünüyor. Kontrol edilecek ilk şey, Rails'in konfigürasyonudur - lütfen Rayların geliştirme modunda olmadığından ve config.threadsafe! üretim ortamınızda etkin. Threadsafe modu, uygulamanız çalışırken belleğe yüklenen Rails'in yalnızca bir paylaşılan kopyasıyla sonuçlanacak.

Ayrıca, veritabanı yapılandırmanızın bağlantı havuzundan faydalandığından emin olun, ör. pool: 20 içinde database.yml.

Son olarak, JVM ve JRuby ayarlarınızı kontrol edin - her ikisi de yüksek oranda ayarlanabilir. Başlangıçta JVM'ye ayrılan bellek yeterli olduğundan ve uygulamanızın normal düzgün çalışması için yeterli bellek olduğundan emin olmanız gerekir; Aksi takdirde JVM, performansı önemli ölçüde düşürecek olan, erken ve sık toplanan çöplere sürekli olarak zorlanacaktır.

Örneğin, mütevazı bir şekilde VPS'nin bazı ayarları aşağıdaki gibi olabilir:

-Xmx500m -Xss1024k -Djruby.memory.max=500m -Djruby.stack.max=1024k

... ama bu ayarları körü körüne kopyalamayın! Sunucunuzda bulunan bellek kaynakları ile ilgili olarak sizin için neyin iyi olduğunu deneyimlemeniz ve denemeniz gerekecektir.

Buna göre, JRuby muhtemelen MRI altında birden fazla Rails işleminin toplamından daha az bellek tüketirken, tek bir JVM işlemi için kesinlikle biraz daha fazla ön ayırmanız gerekecektir. JRuby için cömert ol, ve JRuby senin nezaket :-) için ödüllendirecek

JRuby ve JVM'yi ayarlama hakkında daha fazla bilgiyi buradan edinebilirsiniz: https://github.com/jruby/jruby/wiki/PerformanceTuning

Güncelleştirme

Ayarlamanıza gerek yok config.threadsafe! içinde Raylar 4.0 ve yukarıda; varsayılan olarak threadafe'tir.


18
2018-04-23 16:09



İçinde çalışan production modu, geliştirme moduna göre bazen 5-6 kat daha hızlı yanıt getirir. En azından benim durumumdaydı. Bunu söylediğin için teşekkürler. - Aleks


Aynı davranışı görüyorum, ama JRuby'nin ısınması için çok daha uzun süre ihtiyaç duyduğunu aklınızdan çıkarmayın. Aslında, JRuby'nin sonunda yakalayacağı konusunda biraz iyimserim.

Birkaç seçenek belirleyerek bu 'ısınmayı' daha hızlı yapmak mümkündür. Ruby -> Java Bytecode derleyicisi, aşağıdaki env varlığını ayarlayarak JIT'e ilk çağrıda her yöntemi derler:

export JRUBY_OPTS="-J-Djruby.jit.threshold=1 -J-Djruby.jit.max=16384"

Benim için, Rails sayfasını birkaç kez yeniledikten sonra, hala MRI Ruby'den 2-3 kat daha yavaş, ama eskisinden en az 3 kat daha hızlı.

Ayrıca, java çalışma zamanının, java bayt kodunu makine koduna benzer şekilde derleyen JIT olduğunu unutmayın, ancak bu JIT, sunucu çalışma zamanını kullanırken bir yöntem 10.000x çağrılıncaya kadar devreye girmeyecektir. Bu olabilir de yapılandırılmış.

export JRUBY_OPTS="-J-Djruby.jit.threshold=10 -J-Djruby.jit.max=16384 -J-XX:CompileThreshold=10" -J-XX:ReservedCodeCacheSize=128M"

Bu seçeneklerle, JRuby on Rails, MRI'dan daha iyi veya daha iyi performans verir.

Lütfen bu seçeneklerin sadece sabırsız değerlendirme için olduğunu unutmayın! Gerçekte, JIT derlemesini bu kadar agresif bir şekilde yürütmek neredeyse her zaman kötü bir fikirdir; JIT derlemesinde sadece birkaç kez çalıştırılabilecek değerli zaman ve bellek harcıyorsunuz. Bununla birlikte, sonuçta ortaya çıkan JRuby performansının, ilk çalıştırmalara göre beklediğinizden daha iyi olabileceğini gösterir.

Bunun sizin için işe yarayıp yaramadığını bana bildirin.


4
2018-01-29 13:48





JAVA 7 ile jruby 1.6.8 veya jruby 1.7.x sürümüne geçin!

Mükemmel performans.

Aynı sorunu ve muazzam derecede hızlı bir şekilde yaşadık (sadece sürümleri değiştirerek).


3
2017-12-13 11:23



Aynı kötü performanslarım var. Yeni bir ray sistemi uygulaması olan java 7 & Jruby 1.7, MRI ile güçlü bir akım projesinden daha yavaş. Erg. - m4tm4t