Ruby 1.9 (YARV) vs. Python, Lua & PHP
Posted by Jarosław Zabiełło Mon, 01 Jan 2007 18:36:00 GMT
Korzystając z tego, że niedawno do repozytorium Rubiego został dodany YARV (wirtualna maszyna Rubiego) pokusiłem się o małe porównanie wydajności. Jako test użyłem prostego programu jaki pojawił się na liście pl.comp.lang.pyhon (musiałem tylko trochę zwiększyć pętle do 10 milionów iteracji, aby były widoczne jakieś wyniki) Użyty sprzęt: Athlon64 3700+, 64bit Ubuntu 6.0.6.
Sprawdziłem też z ciekawości PHP 5.2 na tym samym sprzęcie. Dla tak prostego testu powinien móc dać z siebie wszystko. Jest jednak wolniejszy od Rubiego 1.9.
Kod dla Pythona:
import time
t=time.time()
a=0
for i in xrange(10000000):
a += i
print a
print time.time() - tt = os.clock()
a = 0
for i = 1,10000000 do
a=a+i
end
print(a)
print(os.clock() - t)Kod dla Rubiego:
t = Time.now
a = 0
for i in 1..10_000_000
a = a+i
end
puts a
puts Time.now - tKod dla PHP:
<?php
function microtime_float() {
$time = microtime();
return (double)substr($time, 11) + (double)substr($time, 0, 8);
}
$t = microtime_float();
$a = 0;
for ($i = 0; $i < 10000000; $i++) {
$a += $i;
}
print "$a\n";
print microtime_float()- $t;
?>Wyniki:
- Lua: 1.14 s
- Ruby 1.9: 1.49 s
- PHP 5.2: 1.74 s
- Python 2.5: 2.64 s
- Python 2.4.3: 2.72 s
- Ruby 1.8.5: 3.83 s.
Drugie podejście
Tym razem wynik uśredniam dla 10 prób. Zwiększyłem ilość iteracji do 20 mln. No i… Ruby 1.9 pobił wszystko. Zarówno Pythona jak i Lua! (PHP 5.2 po 30 sek. zgłosił timeout. Musiałem więc uśrednić po 5 wynikach.)
PYTHON
import time
def bench():
a, t = 0, time.time()
for i in xrange(20000000):
a+=i
return time.time()-t
result = 0
for i in range(10):
result += bench()
print result / 10.0RUBY
def bench
a, t = 0, Time.now
20_000_000.times { |i| a += i }
Time.now - t
end
result = 0
10.times { |i| result += bench }
puts result / 10LUA
function bench()
a = 0
t = os.time()
for i = 1, 20000000 do
a = a + i
end
return os.time() - t
end
result = 0
for x = 1,10 do
result = result + bench()
end
print(result/10)PHP
<?php
function bench() {
$a = 0;
$t = time();
for ($i = 0; $i < 20000000; $i++) $a += $i;
return time() - $t;
}
$result = 0;
for ($x = 1; $x <= 5; $x++) $result += bench();
print $result / 5.0;
?>Wyniki
- Ruby 1.9: 2.0953268 s.
- Lua 5.1: 2.4 s.
- Python 2.5: 2.49481592178 s.
- Python 2.4.3: 2.71687791348 s.
- PHP 5.2: 4.2 s.
- Ruby 1.8.5: 9.0153751 s.
Jestem ciekaw kiedy wyjdzie Rails dostosowany do Ruby 1.9. Zapowiada się bardzo obiecująco!


Kanały IRC![[Dilber w Onecie]](/images/larry.png)


Z tego wyglada ze 1.9 jest szybszy o ok 0.6 koszmaru :D
No, niektórzy mówili tak, z przesadą, o “koszmarnej” wydajności. :) Może wydajność nie była nigdy koszmarna, ale na pewno wyraźniej wolniejsza od Pythona. Teraz, dzięki YARV to się radykalnie poprawiło. Już wcześniej można było czytać o poprawie wydajności nawet do 10x (zależy co testować). Ale nie wiadomo było kiedy będzie można było jakoś używać YARV. No i niespodzianka, YARV jest w trunk SVN dla Rubiego 1.9.x. Zatem skompilowałem, zapuściłem test i wyniki są jakie są. :)
Ja tylko wspomnę tak trochę offtopicowo, że w php.ini można zmienić maksymalny czas wykonywania skryptu – domyślnie to właśnie 30s.
PHP 5.14 – 2.6s dla 2 mln (drugi kod). Test wydaje mi się mocno naciągany i niewiarygodny na korzyść Rubiego. Panie Jarku – nie jest Pan obiektywny. Ruby fajna sprawa, ale warto przeprowadzać testy rzetelnie. :)
A ja tylko dodam, że w tytuł można by zmienić na ‘porównanie pętli for w językach…’.
Poza tym zwróć uwagę, że dla Ruby’ego używasz specjalnie pod niego skonfigurowaną wirtualną maszynę, a dla php zapewne w miarę standardowej wersji apacha.
Jak dla mnie to porównanie nic nie mówi o faktycznej szybkości języków.
Moją uwagę zwróciło to, że w drugim teście wyniki dla pythona zmieniły się minimalnie, a python2.5 wykonał pętle dłuższą szybciej niż krótszą. Trochę to dziwne.
Link do benchmarka
http://shootout.alioth.debian.org/debian/benchmark.php?test=all&lang=ruby&lang2=php
ten wynik to zasługa OPT_SPECIALISED_INSTRUCTION (czyli olanie niezredefiniowanej metody Fixnum#+), niedługo będzie jeszcze lepiej…
Chyba nie rozumiecie sensu tego testu. Nikt przecież nie twierdzi, że ten test jest miarodajny i testuje ogólną wydajność języków. Chodzi o sam fakt – wersja Rubiego 1.8.5 jest sporo wolniejsza od PHP i Pythona, a wersja 1.9 z przepisanym VM szybsza. Trzeba poczekać na jakieś bardziej rozbudowane testy – to pokazuje tylko, że rozwój Rubiego idzie w dobrą stronę
YARV to jest po prostu inna wirtualna maszyna, inna implementacja. Matz pisząc swój interpreter nie stawiał tak bardzo na szybkość. Do listopada 2007 Ruby z YARV’em ma być już w stabilnej oficjalnej wersji, więc nie nazywałbym tego “specjalnie pod niego skonfigurowaną wirtualną maszyną”. :)
Dokładnie, wraz z ze wzrostem stabilności i funkcjonalności będzie więcej wiadomo. Wydajność (prawie) nigdy nie była brana pod uwagę przy projektownaniu Rubiego (większe optymalizacje zaczęły się dopiero jakies 5 lat temu – 1.6 to był koszmar). Z drugiej strony implementacja Fixnuma to jedno ze sprytniejszych oszustw wziętych żywcem z lispa (tagowanie wskaźników). YARV zawsze był tworzony specjalnie dla Rubiego – w końcu to Yet Another Ruby Virtual machine…
Azzazael: nie podałeś sprzętu jaki użyłeś i dałeś 10x mniej interacji. Ja testowałem dla 20mln, a nie 2mln.
Rafał Wysocki: trudno uzyskać identycznych (co do milisekundy) wyników, bo na tym serwerze też chodzą jakieś programy. Dlatego, wynik to uśredniona wartość po 10 próbach.
http://www.rubychan.de/share/yarv_speedups.html
Drogomir: przeczytaj tytuł tego artykułu, a potem mów o sensie. Ja tylko napisałem, że jest on nieadekwatny do treści.
Nie twierdzę, że Ruby nie idzie w dobrą stronę, tylko autor albo powinien zająć się analizą postępów Ruby’ego, albo przygotować rzetelne testy porównawcze.
Uśrednianie wyników w takich testach jest złe. Lepiej zrobić te 20 powtórzeń i dla każdego języka wziąć najlepszy wynik, to ma większy sens wg. mnie.
function microtime_float() { $time = microtime(); return (double)substr($time, 11) + (double)substr($time, 0, 8); }
Przeciez jest microtime( true ) , ktore zwraca floata (dostepne w php5+) :D
These tests are saying nothing really. Do yourself the favor of doing proper comparision next time please, that would include things like function call speed, class features, recursion, mathematical expression, closures, etc. There are many many tests you can apply. a+=1 isn’t very conclusive.
doc: It was not intended to be comprehensive. It was only a simple try. I have added also second test, when Python is faster.
to może zrób trzeci test w którym java bedzie najszybsza
A co mnie jakaś Java obchodzi? Może jeszcze test assemblera, co? Interesowało mnie tylko porównanie wybranych języków dynamicznych, wysokopoziomowych.