JRuby vs. Python vs. PHP vs. Ruby
Wysłane przez Marek Tenus (~marcus) dnia 13.01.2008
Pojawiła się wersja 1.1 RC jruby jest zatem powód do tego, aby sprawdzić, czy zapowiedzi co do szybkości i wydajności interpretera są prawdziwe. By jednak artykuł nie był zbyt subiektywny i lakoniczny, pozwoliłem sobie porównać kilka interpreterów Ruby z Pythonem i PHP w odniesieniu do szybkości ich działania. Artykuł ten jest kontynuacją benchmarków przeprowadzonych przez Jarosława Zabiełło (hipertracker ) „Python vs. Ruby 1.9 YARV. Cz. II" (polecam przed przeczytaniem tego artykułu zapoznać się z tym wątkiem).
Pojawiła się wersja 1.1 RC jruby jest zatem powód do tego, aby sprawdzić, czy zapowiedzi co do szybkości i wydajności interpretera są prawdziwe. By jednak artykuł nie był zbyt subiektywny i lakoniczny, pozwoliłem sobie porównać kilka interpreterów Ruby z Pythonem i PHP w odniesieniu do szybkości ich działania. Artykuł ten jest kontynuacją benchmarków przeprowadzonych przez Jarosława Zabiełło (hipertracker ) „Python vs. Ruby 1.9 YARV. Cz. II" (polecam przed przeczytaniem tego artykułu zapoznać się z tym wątkiem). Do testów wykorzystałem ten sam algorytm (patrz blog Zabiełły). Różnica moich benchmarków jest taka, że dodatkowo przetestowałem PHP (4i5) i jruby (1.0, 1.1) oraz zastosowałem kilka opcji kompilacji z jruby, by pokazać wam, która jest najlepsza. Do testów wykorzystano następujące interpretery/języki:
- JRuby 1.0 i 1.1
- PHP w wersji 4.4.7 i 5.2.5
- Ruby w wersji 1.8.6 i 1.9
Algorytm w ruby (źródło )
def wariancje(s, n) if n == 0 yield [] else s.size.times do |i| wariancje(s, n-1) { |c| yield [s[i]] + c } end end end t = Time.now s = "abcdefg" size = s.size i = 0 results = [] 10.times do t = Time.now wariancje(s, size) do i += 1 end tmp = Time.now - t results << tmp puts tmp end puts "\n#{results.min}, #{results.max}, #{size}, #{i}"
Algorytm w php
function wariancje($s, $n) { if ($n==0) return array(''); $l = strlen($s); $ret = array(); for ($i=0;$i<$l;$i++){ foreach (wariancje($s, $n-1) as $c){ $ret[] = $s[$i].$c; } } return $ret; } $s = "abcdefg"; $nelem = strlen($s); $i = 0; $results = array(); for ($j=0;$j<10;$j++){ $t = time(); $i += count(wariancje($s, $nelem)); $tmp = time() - $t; $results[] = $tmp; echo $tmp . "\n"; } echo min($results).":".max($results).":$nelem, $i";
Zestaw wyników dla 10 kolejnych prób wywołań metody z interpreterem jruby1.0 przedstawiono poniżej:


Jak widać czasy wykonania są bardzo duże a najlepszy wynik uzyskamy używając jruby1.0 z opcjami -J-server -J-Djruby.compile.frameless=true
Poniżej prześledźmy wykonanie naszego algorytmu dla pozostałych interpreterów/języków.








Prześledziwszy powyższe wykresy i tabele możemy wyciągnąć kilka wniosków:
- Ruby 1.9 jest o 40% szybsze od Ruby 1.8.6
- Użycie psyco z Pythonem 2.5 jest wolniejsze niż użycie samego Pythona
- PHP5 jest znacznie szybsze od wersji PHP4 (o 30%)
- JRuby1.1 jest najszybsze z opcjami -J-server -J-Djruby.compile.frameless=true
Prównajmy teraz wszystkie interpretery/języki o najlepszy wynikach uzyskanych w powyższych zestawieniach:

Powyższy wykres pokazuje, że jruby1.0 jest najmniej wydajnym z interpreterem. Ruby 1.9 wciąż jest wolniejszy od PHP5, choć różnica ta jest znacznie mniejsza niż przy wersji 1.8.6. Jruby z optymalnymi opcjami i Python 2.5 mają niemal identyczne czasy wykonania.
Proponuję jednak jeszcze bliżej przyjrzeć się tym dwóm interpreterom na poniższym wykresie.

Jak widać wykonanie algorytmu z użyciem Pythona jest wciąż szybsze niż z JRuby1.1. Jednak nie można nie zauważyć, że po pierwszym wykonaniu metody przez JRuby kolejne wykonania mają niemal identyczne czasy. Może to świadczyć o tym, że interpreter JRuby1.1 jest stabilniejszy od Pythona 2.5. Poza tym średnia wykonania 10 prób w Pythonie jest jedynie o 0,4 s szybsza niż z użyciem JRuby1.1. Warto zauważyć, że testy przeprowadzono na wersji RC, więc czasy te mogą być jeszcze lepsze dla JRuby1.1.
Zestawienie zbiorcze wyników testów:



Środowisko testowe:
- CPU: 2GHz Intel Celeron (32bit)
- RAM: 1GB
- System: Ubuntu 7.10
- Python, Ruby 1.8.6/1.9, JRuby 1.0 zainstalowane z pakietów
Zapraszam do dyskusji na forum
