Benchmark: Ruby 1.8, Ruby 1.9, JRuby 1.3 RC2
(9 komentarzy)W kategoriach: Rails , Railsfera , Ruby , Techblog / 01 czerwca 2009 [23:35:07]
Tagi technorati: ruby performance benchmark ruby19 jruby programming
Wiele się mówi o szybkości Rubiego. Na pewno dzięki temu jest coraz mniej osób, które uważają, że jest to język zbyt wolny do aplikacji webowych - Merb w końcu pokazał, że potrafi być szybszy niż pythonowi konkurenci (Django, Pylons), a PHP (także pod względem wydajności frameworków) to już nie margines, a zwykła patologia.
Ostatnio modne są microbenchmarki, testujące pojedynczy aspekt języka - wyjątki, rekurencję itp. Jest to oczywista bzdura, która tak naprawdę niczego nie mówi, dlatego postanowiłem zmierzyć wydajność tych języków w czymś realnym.
Co na pokładzie?
C2D 2.4 GHz, 4GB RAM. System operacyjny: Mac OS X 10.5.7
$ ruby -v
ruby 1.8.6 (2008-08-11 patchlevel 287) [i686-darwin9.7.0]
Ruby Enterprise Edition 20090520
$ ruby19 -v
ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-darwin9.6.0]
$ jruby -v
jruby 1.3.0RC2 (ruby 1.8.6p287) (2009-05-27 46598e4)
(Java HotSpot(TM) 64-Bit Server VM 1.6.0_07) [x86_64-java]
Runda pierwsza: rozpoznawanie samogłosek w głosie ludzkim
Coś całkiem mocno wykraczające poza zwykłą pętlę for. Rozpoznawanie następuje oczywiście poprzez sztuczne sieci neuronowe, a konkretniej: wielowarstwowe perceptrony ze wsteczną propagacją błędów. Pomijając szczegóły implementacyjne (w końcu chodzi o wydajność), warto tylko zaznaczyć, że czas uczenia sieci został wydłużony do absurdalnej liczy setek tysięcy cykli uczenia się całkiem niemałej paczki danych treningowych. Wszystko po to, by JVM od JRubiego zdążyła się "rozgrzać" i pokazać pazurki. Jak ostre są te pazurki? Porównacie w testach wydajności poniżej:
Ruby 1.8
real 25m11.525s user 25m6.682s sys 0m1.949s
Ruby 1.9
real 12m39.138s user 12m38.201s sys 0m1.073s
JRuby
real 8m15.320s user 8m12.577s sys 0m4.128s
Tak jak się mówi w wielu miejscach, Ruby 1.9 jest dwukrotnie szybszy niż Ruby 1.8. Natomiast JRuby jest szybszy od Ruby 1.9 o 37%, co jest dość znaczną przewagą.
Runda druga: Rails
Nic wielkiego, testowana jest aplikacja z jedną akcją renderującą zwykły szablon. Nie używamy bazy danych. Całość serwowana przez pojedynczego Mongrela. W przypadku Ruby 1.9 należało wprowadzić parę zmian w kodzie C i .rb, aby rozszerzenie dało radę się skompilować. W przypadku JRubiego serwowanie aplikacji na Mongrelu jest, delikatnie mówiąc, nietypowe, ale potrzebne przy równych (w miarę miarodajnych) testach.
Parametr c mówi o ilości jednoczesnych połączeń podczas testów.
Ruby 1.8
-c 1: 582.73 [#/sec] -c 5: 548.83 [#/sec] -c 20: 524.57 [#/sec]
Ruby 1.9
-c 1: 548.06 [#/sec] -c 5: 501.29 [#/sec] -c 20: 476.33 [#/sec]
JRuby
-c 1: 365.03 [#/sec] -c 5: 493.89 [#/sec] -c 20: 486.92 [#/sec]
Bardzo dziwną rzeczą jest to, że Ruby 1.9 okazał się wolniejszy niż Ruby 1.8! JRuby delikatnie przewyższa 1.9 szybkością przy dużych obciążeniach, ale nadal jest to wolniej niż 1.8.
Runda trzecia: Merb
Typ aplikacji taki sam jak w przypadku Railsów. Pamiętajmy, że tylko Merb 1.1 (edge!) działa z wersją 1.9.
Ruby 1.8
-c 1: 953.38 [#/sec] -c 5: 922.15 [#/sec] -c 20: 915.56 [#/sec]
Ruby 1.9
-c 1: 1146.85 [#/sec] -c 5: 1110.52 [#/sec] -c 20: 1079.74 [#/sec]
JRuby
-c 1: 772.88 [#/sec] -c 5: 1109.98 [#/sec] -c 20: 1079.29 [#/sec]
Tutaj wyniki Ruby 1.9 i JRuby są porównywalne. Nie da się ukryć, że Merb jest lepiej napisany niż Railsy, dlatego im lepsza implementacja tym większy skok wydajności. Rails3 ma mieć ulepszone bebechy, dlatego możemy się spodziewać, że wydajność Rails 3 będzie porównywalna z Merbem.
Co to wszystko znaczy?
- JRuby jest w pełni gotowy do produkcji i jest całkowicie kompatybilny (poza paroma gemami z rozszerzeniami w C) z wersją 1.8. Oznacza to mniej więcej tyle, że w większości przypadków, o ile mamy dużo RAM-u na naszym serwerze, możemy za darmo znacząco zwiększyć wydajność aplikacji zwyczajnie poprzez zmianę implementacji języka na Javową
- JRuby 1.4 będzie jeszcze szybszy
- Java 7 będzie posiadała w swoich bebechach wiele ficzerów, które ułatwiają tworzenie na jej bazie języków dynamicznych - oznaczać to będzie prawdopodobne wyrzucenie części kodu z JRubiego, bo będzie on już w samej platformie Java. Takie zabieg prawdopodobnie zwiększy wydajność JRubiego.
- Tradycyjnie, nowa edycja Javy może zwiększyć jej wydajność, na czym skorzysta JRuby.
- JRuby nie wymaga zgodności gemów z wersją 1.9, a daje porównywalny kop wydajnościowy, co wersja 1.9. Mam nadzieję, że te słowa nie zdemotywują nikogo do reimplementacji swoich bibliotek pod wersję 1.9... Więcej info na isitruby19.com.
- Testy dotyczyły tylko trzech implementacji. Niedługo może się pojawić MagLev, Rubinius i MacRuby
- MacRuby jest projektem wyjątkowo ciekawym. Docelowo ma być kompatybilny z każdym POSIXowym systemem (a więc nie tylko Mac OS X), a także rezygnować z wirtualnej maszyny YARV na rzecz LLVM. Będzie to olbrzymi kop wydajnościowy. Już teraz trunkowa wersja 0.5 potrafi być paręnaście razy szybsza od konkurentów, a skompilowany (tak jest, będzie można kompilować do binarki!) generator ciągu Fibonacciego jest szybszy niż... implementacja w Objective-C! Do tego dochodzi dojrzały generational garbage collector oraz obsługa natywnych wątków. Nie byle jaka implementacja!
teamon
01 czerwca 2009, 23:58:02Wczoraj bawilismy sie troche na http://kodesnippetz.jogger.pl/2009/05/25/zamiana-123456789-na-123-456-789/ i wyszlo z tego http://gist.github.com/121022
To oczywiscie tylko banalny tescik, ale zastanawiajace jest to ze 1.9 okazuje sie ciut wolniejszy od 1.8.6
(Wynik MacRuby to juz w ogole ciekawostka)
lopex
02 czerwca 2009, 14:36:35teamon: czy ten benchmark z gista był uruchamiany z —server ? JRuby dla takich rzeczy powinien być kilkukrotnie szybszy od 1.8 i 1.9 (nawet w trybie zgodności z 1.9). Dla benchmarków intensywnie korzystających ze stringów/regexpów 1.9 będzie zazwyczaj wolniejszy od 1.8 ponieważ za każdym razem musi negocjować kodowania. JRuby w trybie 1.9 jest zaniedbywalnie wolniejszy od trybu 1.8.
teamon
02 czerwca 2009, 14:39:53http://gist.github.com/121022 – update z —server. Wyniki nie są powalające w porównaniu do jruby bez —server.
lopex
02 czerwca 2009, 14:40:29Re, tryby JRuby, oczywiście dla trybu 1.9 JRuby będzie ogólnie szybszy ponieważ w 1.9 zmianie uległy niektóre semantyki języka (np bloki) pozwalające na dodatkowe optymalizacje (jeszcze w JRuby niezaimplementowane). Stringi i Regexpy to jest inna sprawa.
lopex
02 czerwca 2009, 15:51:59razorjack: Teraz zauważyłem że używasz jdk5 i to jeszcze w trybie client. Jest to jedno z najmniej wydajnych środowisk do benchmarkowania JRuby.
Jdk6 potrafi być ok 30-50% szybsze od jdk5 a opcja —server potrafi dać kilkukrotnego boosta.
RazorJack
02 czerwca 2009, 18:16:02@lopex: Wszystkie testy były odpalone w trybie —server. Ale co do wersji JDK, to masz rację. Dzięki za zauważenie. OS X ma domyślnie włączone JDK5, czego się totalnie nie spodziewałem…
Poprawiłem wszystko i odpaliłem testy na nowo. Mam nadzieję, że więcej wpadek nie ma. :)
rubyconvict
21 stycznia 2010, 15:02:04Najświeższy benchmark:
http://rvm.beginrescueend.com/benchmarks/2010-01-06/
JRuby jest średnio równie szybki, a nawet szybszy niż ruby 1.9, ale zobaczcie użycie ramu JRuby, ka-cing! Dlatego JRuby on Rails nigdy stanie się tak popularny jak RoR w zakresie web dev. Czekam na ostrą odpowiedź ze strony javowców ;-)
rubyconvict
28 maja 2010, 01:14:28Nowy gracz na arenie, Rubinius 1.0 wygląda całkiem przyzwoicie:
http://mitkokostov.info/2010/05/22/ruby-vm-shootout.html
rubyconvict
02 sierpnia 2010, 14:24:10Najnowszy:
http://programmingzen.com/2010/07/19/the-great-ruby-shootout-july-2010/