<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Jaros&#322;aw Zabie&#322;&#322;o - BLOG: Tag benchmark</title>
    <link>http://blog.zabiello.com/articles/tag/benchmark</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>moje notatki, linki, komentarze</description>
    <item>
      <title>Passenger bli&#380;ej - Rails, Rack i WSGI</title>
      <description>&lt;p&gt;Stworzony pierwotnie na u&#380;ytek Rails, aktualnie mod_passenger ju&#380; obs&#322;uguje nie tylko Rails ale tak&#380;e mas&#281; innych framework&#243;w u&#380;ywaj&#261;cych Rack&amp;#8217;a. W &lt;a href="http://tinyurl.com/6edmve"&gt;nowej dokumentacji&lt;/a&gt; wymienione s&#261; frameworki: &lt;a href="http://code.whytheluckystiff.net/camping"&gt;Camping&lt;/a&gt;, &lt;a href="http://halcyon.rubyforge.org/"&gt;Halcyon&lt;/a&gt;, &lt;a href="http://www.mackframework.com/"&gt;Mack&lt;/a&gt;, &lt;a href="http://merbivore.org/"&gt;Merb&lt;/a&gt;, &lt;a href="http://ramaze.net/"&gt;Ramaze&lt;/a&gt; i &lt;a href="http://sinatrarb.com/Home"&gt;Sinatra&lt;/a&gt;. W dokumentacji nie wymieniono jeszcze &amp;#8220;drugiej listy&amp;#8221;, zawieraj&#261;cej frameworki korzystaj&#261;ce z &lt;a href="http://www.wsgi.org/wsgi"&gt;&lt;span class="caps"&gt;WSGI&lt;/span&gt;&lt;/a&gt; i Pythona (np. &lt;a href="http://pylonshq.com/"&gt;Pylons&lt;/a&gt;, &lt;a href="http://djangoproject.com"&gt;Django&lt;/a&gt;, &lt;a href="http://turbogears.org/"&gt;TurboGears&lt;/a&gt; itp.). Chc&#261;c sprawdzi&#263; plotki wok&#243;&#322; tej sprawy, sprawdzi&#322;em, czy faktycznie mod_passenger pracuje nie tylko z Ruby, ale tak&#380;e z Pythonem. Sprawdzi&#322;em tak&#380;e jak to jest faktycznie z ob&#322;ug&#261; Rails i framework&#243;w na Rack&amp;#8217;u (tu sprawdzi&#322;em tylko Merba). Sprawdzi&#322;em te&#380; JRuby dla Rails i Merba.&lt;/p&gt;


	&lt;p&gt;Wszystkie testy by&#322;y wykonywane na laptopie MacBook Pro Core 2 Duo, 2.16GHZ, 4GB &lt;span class="caps"&gt;RAM&lt;/span&gt; (OSX 10.5.3 dla tego modelu widzi tylko 3GB) i dyskiem 200GB kr&#281;c&#261;cym si&#281; z szybko&#347;ci&#261; 7200 rpm. Ruby 1.8.6, Python 2.5.2, Apache 2.2.8 (mpm-prefork) by&#322;y instalowane z MacPort&#243;w. Passenger, mimo &#380;e instalowany &lt;a href="http://github.com/FooBarWidget/passenger/tree/master"&gt;ze &#378;r&#243;de&#322;&lt;/a&gt; w Apache&amp;#8217;u by&#322; wy&#347;wietlany jako &amp;#8220;Phusion_Passenger/1.1.0&amp;#8221; (by&#263; mo&#380;e wi&#281;c to nie jest jeszcze ta nowa wersja 2.0 o kt&#243;rej pisa&#322;em &lt;a href="http://blog.zabiello.com/articles/2008/06/04/passenger2-ruby-enterprise"&gt;wcze&#347;niej&lt;/a&gt;) Nie sprawdza&#322;em Linuksa, by&#263; mo&#380;e wyniki i wnioski b&#281;d&#261; wtedy inne.&lt;/p&gt;


	&lt;p&gt;Dla tych co chcieliby sami popr&#243;bowa&#263; podaj&#281; wpierw konfiguracj&#281; serwer&#243;w wirtualnych dla Apache&amp;#8217;a potrafi&#261;c&#261; unie&#347;&#263; razem: &lt;span class="caps"&gt;PHP&lt;/span&gt; (2.5.6), Rails (2.1), Merb (0.9.4 edge), i Django (edge).&lt;/p&gt;


	&lt;h2&gt;Konfiguracja Apache&amp;#8217;a  2.2.8&lt;/h2&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_apache "&gt;
# Ruby (Rails):
&amp;lt;VirtualHost *:80&amp;gt;     
  DocumentRoot &amp;quot;/opt/local/apache2/vhosts/rails_app/public&amp;quot;  
  ServerName rails_app
&amp;lt;/VirtualHost&amp;gt;

# Ruby (Merb):        
&amp;lt;VirtualHost *:80&amp;gt;  
  RailsAutoDetect off  
  DocumentRoot &amp;quot;/opt/local/apache2/vhosts/merb_app/public&amp;quot;    
  ServerName merb_app       
&amp;lt;/VirtualHost&amp;gt;

# Python (WSGI):
&amp;lt;VirtualHost *:80&amp;gt;          
  DocumentRoot &amp;quot;/opt/local/apache2/vhosts/wsgi_app/public&amp;quot;    
  ServerName wsgi_app
&amp;lt;/VirtualHost&amp;gt;      

# Django (mod_python)
&amp;lt;VirtualHost *:80&amp;gt;         
  DocumentRoot &amp;quot;/opt/local/apache2/vhosts/djangus/public&amp;quot;    
  ServerName django_modpython 
  &amp;lt;Location &amp;quot;/&amp;quot;&amp;gt;
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE djangus.settings
    PythonDebug On        
    PythonPath &amp;quot;['/opt/local/apache2/vhosts'] + sys.path&amp;quot;    
  &amp;lt;/Location&amp;gt;       
&amp;lt;/VirtualHost&amp;gt;   

# PHP:
&amp;lt;VirtualHost *:80&amp;gt;  
  RailsAutoDetect off  
  DocumentRoot &amp;quot;/opt/local/apache2/vhosts/php_app/public&amp;quot;        
  ServerName php_app   
&amp;lt;/VirtualHost&amp;gt;    &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Wszystkie aplikacje korzystaj&#261;ce z mod_passengera musz&#261; posiada&#263; folder &lt;code&gt;public&lt;/code&gt; i &lt;code&gt;tmp&lt;/code&gt;. Gdy do katalogu &lt;code&gt;tmp&lt;/code&gt; dorzucimy jakikolwiek (mo&#380;e by&#263; pusty) plik o nazwie &lt;code&gt;restart.txt&lt;/code&gt;, to przy nast&#281;pnym prze&#322;adowaniu przegl&#261;darki nast&#261;pi restart aplikacji.&lt;/p&gt;


	&lt;p&gt;We wszystkich przypadkach u&#380;y&#322;em dosy&#263; banalnego kodu polegaj&#261;cego na wy&#347;wietleniu &amp;#8220;Hello World!&amp;#8221;. Z wynik&#243;w programu &lt;code&gt;ab&lt;/code&gt; wyci&#261;&#322;em nieistotne informacje.&lt;/p&gt;


	&lt;h2&gt;Rails (2.1)&lt;/h2&gt;


	&lt;h3&gt;Rails 2.1 + mod_passenger 1.1.0&lt;/h3&gt;


	&lt;p&gt;Rails obs&#322;ugiwane s&#261; w Passengerze praktycznie bezobs&#322;ugowo. Wystarczy wkopiowa&#263; pliki na serwer i to wszystko.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;ab -n 1000 -c 1 http://rails/ 
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Total transferred:      582000 bytes
HTML transferred:       12000 bytes
Requests per second:    430.20 [#/sec] (mean)
Transfer rate:          244.35 [Kbytes/sec] received

ab -n 1000 -c 4 http://rails/
...
Concurrency Level:      4
Failed requests:        239
   (Connect: 0, Length: 239, Exceptions: 0)
Write errors:           0
Total transferred:      488073 bytes
HTML transferred:       9132 bytes
Requests per second:    520.75 [#/sec] (mean)
Transfer rate:          247.88 [Kbytes/sec] received&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; 

	&lt;p&gt;Szybko&#347;&#263; nie jest najgorsza, ale niepokoj&#261;ca jest du&#380;a lista b&#322;&#281;dnych request&#243;w w wypadku zapyta&#324; r&#243;wnoleg&#322;ych. Jak si&#281; dalej okazuje, ten problem dotyczy tak&#380;e ob&#322;ugi Rack jak i &lt;span class="caps"&gt;WSGI&lt;/span&gt;. Albo to jaka&#347; specyfika &lt;span class="caps"&gt;OSX&lt;/span&gt;, albo wcale nie jest tak dobrze ze stabilno&#347;ci&#261; mod_passengera dla r&#243;wnoleg&#322;ych zapyta&#324;. Trzeba by by&#322;o te&#380; zbada&#263;, czy ten efekt wyst&#281;puje tak&#380;e dla Linuksa. Zdziwi&#322;bym si&#281; gdyby tam by&#322;o podobnie skoro Dreamhost ju&#380; oferuje hosting z mod_rails&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Dla por&#243;wnania Rails u&#380;ywaj&#261;cy Mongrela, Thin oraz Ebb. Mo&#380;na by pokusi&#263; aby odpali&#263; Ebb i Thina na uniksowych socketach (Ebb te&#380; to ju&#380; potrafi!), ale wtedy musia&#322;bym zestawia&#263; klaster i uruchamia&#263; to przez proxy. Jak kto&#347; chce to niech si&#281; sam pobawi. Dla prostoty u&#380;y&#322;em port&#243;w &lt;span class="caps"&gt;TCP&lt;/span&gt;. Sprawdzi&#322;em te&#380; JRuby.&lt;/p&gt;


	&lt;h3&gt;Rails 2.1 + Ebb 0.2.0&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;ebb_rails -e production start

ab -n 1000 -c 1 http://127.0.0.1:3000/
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    488.95 [#/sec] (mean)

ab -n 1000 -c 4 http://127.0.0.1:3000/
..
Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    533.22 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; 

	&lt;p&gt;Szybko&#347;&#263; wi&#281;ksza od mod_passengera i co wa&#380;niejsze, zero jakichkolwiek b&#322;&#281;d&#243;w przy pracy r&#243;wnoleg&#322;ej.&lt;/p&gt;


	&lt;h3&gt;Rails 2.1 + Thin 0.8.1&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;thin start -e production              

ab -n 1000 -c 1 http://127.0.0.1:3000/
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    485.95 [#/sec] (mean)

ab -n 1000 -c 4 http://127.0.0.1:3000/
...              
Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    506.21 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Szybko&#347;&#263; troch&#281; mniejsza od Ebb, ale stabilno&#347;&#263; b. dobra.&lt;/p&gt;


	&lt;h3&gt;Rails 2.1 + Mongrel 1.1.5&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;script/server -e production

ab -n 1000 -c 1 http://127.0.0.1:3000/
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    373.74 [#/sec] (mean)

ab -n 1000 -c 4 http://127.0.0.1:3000/
...
Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    360.46 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Stabilno&#347;&#263; bez zarzutu, wydajno&#347;&#263; jednak mniejsza od serwer&#243;w pracuj&#261;cych asynchronicznie.&lt;/p&gt;


	&lt;h3&gt;Rails 2.1 + JRuby 1.1.2&lt;/h3&gt;


	&lt;p&gt;W wypadku JRuby trzeba go troch&#281; &amp;#8220;rozgrza&#263;&amp;#8221;. Pe&#322;na wydajno&#347;&#263; Javy pojawia si&#281; po jakim&#347; czasie pracy. Wynika to ze specyfiki i mo&#380;liwo&#347;&#263;i &lt;span class="caps"&gt;JVM&lt;/span&gt; kt&#243;ra dokonuje dynamicznych optymalizacji kodu w trakcie jego dzia&#322;ania (z tego powodu Java potrafi przewy&#380;szy&#263; wydajno&#347;ci&#261; C++). &amp;#8220;Dla rozgrzewki&amp;#8221; przepu&#347;ci&#322;em Rails przez 30 tys. request&#243;w co spowodowa&#322;o &#380;e pocz&#261;tkowych 137 req/s zrobi&#322;o si&#281; 257 req/s.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;jruby script/server -e production    

ab -n 1000 -c 1 http://127.0.0.1:3000/
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    200.48 [#/sec] (mean)

ab -n 1000 -c 4 http://127.0.0.1:3000/
...
Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    257.05 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;JRuby jest stabilny ale z wydajno&#347;ci&#261; dla Rails jeszcze jest troch&#281; do poprawienia. Dorzucenie opcji optymalizacyjnych, czyli odpalenie Rails przez&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;  
jruby -J-server -J-Djruby.compile.frameless=true script/server -e production&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;troch&#281; poprawi&#322;o wynik: 273 req/s, ale generalnie nie jest to wielka r&#243;&#380;nica. JRuby 1.1.x ju&#380; ma domy&#347;lnie pow&#322;&#261;czane optymalizacje.&lt;/p&gt;


	&lt;h3&gt;Rails &amp;#8211; wnioski&lt;/h3&gt;


	&lt;p&gt;mod_passenger dla Rails faktycznie jest wydajny, cho&#263; trzeba jeszcze by zbada&#263; dlaczego zwraca tyle b&#322;&#281;dnych request&#243;w dla r&#243;wnoleg&#322;ych zapyta&#324; i czy ten problem wyst&#281;puje te&#380; na Linuksie. Dlatego na razie najwydajniejszym i najstabilniejszym rozwi&#261;zaniem dla Rails wci&#261;&#380; pozostaje kombinacja nginx + proxy do ebb lub thin. mod_passenger kusi g&#322;&#243;wnie prostot&#261; konfiguracji (w&#322;a&#347;ciwie brakiem konfiguracji). No i chyba ja to testowa&#322;em dla mod_passengera w wersji 1.1, a nie 2.0 (przynajmniej taka si&#281; wy&#347;wietla w Apache).&lt;/p&gt;


	&lt;h2&gt;Merb 0.9.4 edge&lt;/h2&gt;


	&lt;h3&gt;Merb 0.9.4 edge + mod_passenger 1.1.0&lt;/h3&gt;


	&lt;p&gt;Aby u&#380;y&#263; frameworka Rack z Passengerem trzeba w katalogu projektu tworzy&#263; plik &lt;code&gt;config.ru&lt;/code&gt; zawieraj&#261;cy konfiguracj&#281; Rack&amp;#8217;a. W wypadku Merba b&#281;dzie to&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rubygems&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;merb-core&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;setup&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:merb_root&lt;/span&gt;   &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;.&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt;
                   &lt;span class="symbol"&gt;:environment&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;ENV&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;RACK_ENV&lt;/span&gt;&lt;span class="punct"&gt;'])&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;environment&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Config&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:environment&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;root&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Config&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:merb_root&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;BootLoader&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;run&lt;/span&gt;

&lt;span class="ident"&gt;run&lt;/span&gt; &lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Rack&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Application&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    762.62 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        247
   (Connect: 0, Length: 247, Exceptions: 0)
Write errors:           0
Requests per second:    985.15 [#/sec] (mean) &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Merb jest wci&#261;&#380; du&#380;o szybszy od Rails. Podobnie jak dla Rails, wiele r&#243;wnoleg&#322;ych zapyta&#324; nie zosta&#322;o poprawnie wykonanych. Na produkcyjne u&#380;ycie Passengera dla Merba jest jeszcze troch&#281; za wcze&#347;nie.&lt;/p&gt;


	&lt;h3&gt;Merb 0.9.4 edge + ebb 0.2.0&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;merb -e production -a ebb  
...                              
Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    1463.69 [#/sec] (mean)

Concurrency Level:      10
Failed requests:        0
Write errors:           0
Requests per second:    1560.60 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  

	&lt;p&gt;Merb na Ebb deklasuje wydajno&#347;ci&#261; wszystkie inne rozwi&#261;zania. Tylko czysty &lt;span class="caps"&gt;PHP&lt;/span&gt; jest w stanie mu dor&#243;wna&#263;, ale por&#243;wnywanie &lt;span class="caps"&gt;PHP&lt;/span&gt; z ca&#322;ym, z&#322;o&#380;onym frameworkiem Rubiego jest troch&#281; bez sensu. Z tego co m&#243;wi&#322; ostatnio (na kanale &lt;span class="caps"&gt;IRC&lt;/span&gt;) Ezra Zygmuntowicz, podpi&#281;cie Ebb na czystym Rack&amp;#8217;u, daje nawet &lt;strong&gt;7 tys req/s&lt;/strong&gt; i deklasuje (rzekomo) szybkiego &lt;span class="caps"&gt;PHP&lt;/span&gt;. Gadanie o wy&#380;szej wydajno&#347;ci &lt;span class="caps"&gt;PHP&lt;/span&gt; jest po prostu g&#322;upie. Mo&#380;na si&#281; za&#322;o&#380;y&#263;, &#380;e jakiekolwiek por&#243;wnanie frameworka naprzeciw frameworka, tj. Merba z Symfony czy Cake &lt;span class="caps"&gt;PHP&lt;/span&gt;, obna&#380;y bezlito&#347;nie s&#322;abo&#347;ci &lt;span class="caps"&gt;PHP&lt;/span&gt; &lt;a href="http://blog.zabiello.com/articles/2006/07/14/django-i-rails-bij%C4%85-php"&gt;tak, jak to zrobi&#322; Django&lt;/a&gt; w jednym ze starszych test&#243;w.&lt;/p&gt;


	&lt;h3&gt;Merb 0.9.4 edge + thin 0.8.1&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;merb -e production -a thin 
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    1147.78 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    1234.82 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  

	&lt;p&gt;Wydajno&#347;&#263; r&#243;wnie dobra, cho&#263; troch&#281; s&#322;absza od Ebb. Sporo wi&#281;cej od Rails i zero problem&#243;w ze stabilno&#347;ci&#261;.&lt;/p&gt;


	&lt;h3&gt;Merb 0.9.4 edge + mongrel 1.1.5&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;merb -e production -a mongrel
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    868.10 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    837.01 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;   

	&lt;p&gt;Mongrel jest wolniejszy od serwer&#243;w asynchronicznych ale i tak wyra&#378;nie szybszy od Rails.&lt;/p&gt;


	&lt;h3&gt;Merb 0.9.4 edge + JRuby 1.1.2&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt; 
jruby -S merb -e production 
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    449.52 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    505.52 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Merb na &amp;#8220;rozgrzanym&amp;#8221; (30 tys. req) JRuby osi&#261;ga wydajno&#347;&#263; tak&#261; jak najszybsze rozwi&#261;zania dla Rails z u&#380;yciem asynchronicznego Ebb! To znaczy, &#380;e u&#380;ycie produkcyjne Merba w systemach Javy ma jak najbardziej sens.&lt;/p&gt;


	&lt;h2&gt;Passenger &amp;#38; &lt;span class="caps"&gt;WSGI&lt;/span&gt;&lt;/h2&gt;


	&lt;p&gt;Pora na przyjrzenie si&#281; temu jak mod_passenger daje sobie rad&#281; z Pythonem. W katalogu ze &#378;r&#243;d&#322;ami Passengera le&#380;y gotowa, prosta aplikacja &lt;span class="caps"&gt;WSGI&lt;/span&gt;. Dzieki dobrej dokumentacji Django, uda&#322;o mi si&#281; uruchomi&#263; ten framework pod Passengerem. Gorzej by&#322;o z Pylons. Nie uda&#322;o mi si&#281; stworzy&#263; poprawnego pliku passenger_wsgi.py, niezb&#281;dnego do tego aby Passenger uruchomi&#322; aplikacj&#281; &lt;span class="caps"&gt;WSGI&lt;/span&gt;.&lt;/p&gt;


	&lt;h3&gt;Django edge&lt;/h3&gt;


	&lt;p&gt;Django, mimo swych zalet, stosuje bardzo g&#322;upi&#261; polityk&#281; nie wypuszczania kolejnych wersji kodu. Dost&#281;pna na stronie wersa 0.96 jest stara i generalnie zaleca si&#281; aby u&#380;ywa&#263; nowsz&#261; wersj&#281;, kt&#243;ra istnieje tylko w repozytorium Subversion. Oparcie kodu produkcyjnego o wersj&#281; edge jest troch&#281; ryzykowne i szybko sprowadza si&#281; do z&#322;ej praktyki ci&#261;g&#322;ego  &#322;atania kodu.&lt;/p&gt;


	&lt;p&gt;W wypadku Django plik &lt;code&gt;passenger_wsgi.py&lt;/code&gt; zawiera kod:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;
&lt;span class="ident"&gt;sys&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;append&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;/bezwl/sciezka/do/nazwaprojektu&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; 
&lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;environ&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;DJANGO_SETTINGS_MODULE&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;nazwaprojektu.settings&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;core&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;handlers&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;wsgi&lt;/span&gt;
&lt;span class="ident"&gt;application&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;core&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;handlers&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;wsgi&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;WSGIHandler&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;  ab -n 10000 -c 10            
  ...   
  apr_poll: The timeout specified has expired (70007)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Test pad&#322; po 9tys requestach. Dalej nie mo&#380;na by&#322;o uruchomi&#263; Django. Dopiero restart calego Apache&amp;#8217;a pom&#243;g&#322;. Dla ni&#380;szej ilo&#347;ci r&#243;wnoleg&#322;ych zapyta&#324; (ab -n 1000 -c 4) Django nie pad&#322;o, ale by&#322;o du&#380;o b&#322;&#281;dnych request&#243;w. Okaza&#322;o si&#281;, &#380;e problem wynika&#322; z r&#243;wnoczesnej obecno&#347;ci modu&#322;u mod_python i mod_passenger. Nie mo&#380;na ich razem w&#322;&#261;cza&#263;.&lt;/p&gt;


	&lt;p&gt;Usuni&#281;cie mod_passengera i zostawienie samego mod_pythona pomog&#322;o. (Albo jest jaki&#347; konflikt mi&#281;dzy nimi, albo (co bardziej jest prawdopodobne) trzeba poczeka&#263; na opcj&#281; wy&#322;&#261;czaj&#261;c&#261; passengera dla serwera wirtualnego u&#380;ywaj&#261;cego mod_pythona. Dla Rails i Rack s&#261; takie opcje (RailsAutoDetect, RackAutoDetect), dla &lt;span class="caps"&gt;WSGI&lt;/span&gt; nie mog&#322;em nic takiego znale&#378;&#263; w kodzie &#378;r&#243;d&#322;owym. Modu&#322;u mod_wsgi nie sprawdza&#322;em, bo nie by&#322;o go dost&#281;pnego w portach &lt;span class="caps"&gt;OSX&lt;/span&gt;.)&lt;/p&gt;


	&lt;p&gt;Po zablokowaniu mod_passenger&amp;#8217;a tym razem mod_python nie zwraca&#322; &#380;adnego b&#322;&#281;dnego requestu.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    934.87 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    1240.26 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Nie jest &#378;le. Django jest tu wyra&#378;nie szybsze od Rails (co nikogo nie dziwi), ale jest wolniejsze od Merba, co dla mi&#322;o&#347;nik&#243;w Pythona mo&#380;e by&#263; przykr&#261; niespodziank&#261;. Wi&#281;kszo&#347;&#263; krytyki Rubiego oparta jest na krytyce (s&#322;abszej) wydajno&#347;ci Rails&#243;w. Okazuje si&#281;, &#380;e winny nie jest Ruby, ale s&#322;abo zoptymalizowany Rails. Merb jest dowodem na to, &#380;e mo&#380;na napisa&#263; w Rubim framework, kt&#243;ry nie tylko b&#281;dzie partnerem dla rozwi&#261;zan Pythona, ale nawet potrafi je przewy&#380;sza&#263; wydajno&#347;ciowo.&lt;/p&gt;


	&lt;p&gt;Zobaczmy jak wypadnie &lt;strong&gt;mod_passenger&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    904.60 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        240
   (Connect: 0, Length: 240, Exceptions: 0)
Write errors:           0
Requests per second:    497.51 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;W pracy jednoprocesowej nie mo&#380;na mie&#263; zastrze&#380;e&#324;. Szybko&#347;&#263; jest niez&#322;a. Niestety praca r&#243;wnoleg&#322;a to pora&#380;ka. Du&#380;o request&#243;w nie zosta&#322;o obs&#322;u&#380;onych. Gorzej, za drugim razem (tylko dla 4 rownoleg&#322;ych zapyta&#324;) Django kompletnie si&#281; za&#322;ama&#322;o i zwr&#243;ci&#322;o wyj&#261;tek &amp;#8220;apr_poll: The timeout specified has expired (70007)&amp;#8221;. Nie mo&#380;na by&#322;o go d&#322;u&#380;ej u&#380;ywa&#263;. Wymagany by&#322; restart Apache&amp;#8217;a.&lt;/p&gt;


	&lt;p&gt;Aby sprawdzi&#263; czy to tylko problem Django czy og&#243;lnie implementacji &lt;span class="caps"&gt;WSGI&lt;/span&gt; dla mod_passengera, uruchomi&#322;em test na prostej aplikacji &lt;span class="caps"&gt;WSGI&lt;/span&gt;. Niestety sytuacja jest ta sama.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Wniosek&lt;/strong&gt;: mod_passenger dla Pythona wymaga dopracowania pracy r&#243;wnoleg&#322;ej. Jeszcze za wcze&#347;nie aby go u&#380;ywa&#263; z Pythonem. Ale z drugiej strony uruchomi&#322;em mod_passengera z &lt;span class="caps"&gt;WSGI&lt;/span&gt;  troch&#281; przedwcze&#347;nie. Nie ma przecie&#380; w manualu ani jednego zdania o tym, &#380;e Passenger dzia&#322;a z &lt;span class="caps"&gt;WSGI&lt;/span&gt;. Opar&#322;em si&#281; tylko na pog&#322;oskach i wygrzeba&#322;em t&#261; opcj&#281; ze &#378;r&#243;de&#322;. Wi&#281;c jeszcze wszystko mo&#380;e si&#281; tu zmieni&#263;. To samo dotyczy Rack&amp;#8217;a. Tw&#243;rcy musz&#261; przyjrze&#263; si&#281; problemom zwi&#261;zanym z obs&#322;ug&#261; r&#243;wnoleg&#322;ych zapyta&#324;.&lt;/p&gt;


	&lt;h3&gt;Update&lt;/h3&gt;


	&lt;p&gt;Jednak dobrze si&#281; domy&#347;la&#322;em, Apache nie oszukiwa&#322;. W tek&#347;cie testowa&#322;em starszego Passengera 1.1. Tak&#380;e nie by&#322; to Ruby Enterprise. &lt;span class="caps"&gt;NOWY&lt;/span&gt; Passenger 2.0RC1 oraz Ruby Enterprise zosta&#322; dopiero niedawno &lt;a href="http://blog.phusion.nl/2008/06/09/phusion-passenger-20-rc-1-and-ruby-enterprise-edition-released/"&gt;opublikowany&lt;/a&gt;. Co ciekawe, dodano obs&#322;ug&#281; Apache &lt;span class="caps"&gt;MPM&lt;/span&gt; &lt;strong&gt;Worker&lt;/strong&gt; a nie &lt;span class="caps"&gt;MPM&lt;/span&gt; Prefork, co dodatkowo zmniejsza zu&#380;ycie pami&#281;ci. Niestety Passenger 2.0RC1 jest na razie dost&#281;pny tylko w wersji na Linuksa.&lt;/p&gt;</description>
      <pubDate>Sat, 07 Jun 2008 15:24:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:1dc84c82-1634-41dd-9aa1-9c744a876dff</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/06/07/passenger-rack-wsgi</link>
      <category>rails</category>
      <category>ruby</category>
      <category>python</category>
      <category>django</category>
      <category>merb</category>
      <category>apache</category>
      <category>benchmark</category>
      <category>jruby</category>
    </item>
    <item>
      <title>PostgreSQL vs MySQL vs MSSQL2K</title>
      <description>&lt;p&gt;Zawsze dziwi&#322;em si&#281; dlaczego aplikacje komunikuj&#261;ce si&#281; z &lt;span class="caps"&gt;MSSQL&lt;/span&gt; chodz&#261; tak niemrawo. Zrobi&#322;em sobie szybki test szybko&#347;ci. Na tym samym komputerze zainstalowa&#322;em: &lt;span class="caps"&gt;MSSQL 2000 SP4&lt;/span&gt;, MySQL 5.0.27 i PostgreSQL 8.2.3. Zadanie by&#322;o proste, pobra&#263; list&#281; tabel w bazie.&lt;/p&gt;


	&lt;p&gt;U&#380;yto nast&#281;puj&#261;cego kodu w Pythonie:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;adodbapi&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;MySQLdb&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;odbc&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;psycopg2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;
&lt;span class="ident"&gt;conn&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;
  &lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;mysql&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="constant"&gt;MySQLdb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connect&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;root&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;SHOW TABLES&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt;
  &lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;pgsql&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;psycopg2&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connect&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;user='postgres' password='test''&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;),&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;SELECT * FROM pg_tables jdb273&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt;
  &lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;mssql ado&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;adodbapi&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connect&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;Provider=SQLNCLI.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=test&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;EXEC sp_tables&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt;
  &lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;mssql odbc&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;odbc&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;odbc&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;DRIVER={SQL Server};SERVER=localhost;DATABASE=test;UID=sa;PWD=test&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;EXEC sp_tables&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt;
  &lt;span class="punct"&gt;]&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;repeat&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;100&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
  &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;c&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;conn&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
    &lt;span class="ident"&gt;dbtype&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;sql&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;c&lt;/span&gt;
    &lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;dbtype&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
    &lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
    &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;range&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;repeat&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
      &lt;span class="ident"&gt;cursor&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;cursor&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
      &lt;span class="ident"&gt;cursor&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;execute&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;sql&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="ident"&gt;rows&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;cursor&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;fetchall&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
      &lt;span class="ident"&gt;cursor&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;close&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
    &lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;%d req/s&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;%&lt;/span&gt; &lt;span class="ident"&gt;round&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;repeat&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;__name__&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;__main__&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt;
  &lt;span class="ident"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;U&#380;yta konfiguracja:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;WinXP Pro 2000 &lt;span class="caps"&gt;SP2&lt;/span&gt;, P4 3.2GHz, 1GB &lt;span class="caps"&gt;RAM&lt;/span&gt;.&lt;/li&gt;
		&lt;li&gt;Python 2.5&lt;/li&gt;
		&lt;li&gt;MySQL v5.0. 27, driver: MySQLdb v1.2.2&lt;/li&gt;
		&lt;li&gt;PostgreSQL v8.2.3, driver: psycopg2 v2.0.6b1 (dec dt ext pq3)&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;MSSQL 2000 SP4&lt;/span&gt;, driver: &lt;span class="caps"&gt;ADO&lt;/span&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Wyniki:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;:\&lt;/span&gt;&lt;span class="ident"&gt;home\app\bench\scripts&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ident"&gt;bench_db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;py&lt;/span&gt;
&lt;span class="ident"&gt;mysql&lt;/span&gt; &lt;span class="number"&gt;457&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;pgsql&lt;/span&gt; &lt;span class="number"&gt;581&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;mssql&lt;/span&gt; &lt;span class="ident"&gt;ado&lt;/span&gt; &lt;span class="number"&gt;6&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;mssql&lt;/span&gt; &lt;span class="ident"&gt;odbc&lt;/span&gt; &lt;span class="number"&gt;9&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;

&lt;span class="constant"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;:\&lt;/span&gt;&lt;span class="ident"&gt;home\app\bench\scripts&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ident"&gt;bench_db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;py&lt;/span&gt;
&lt;span class="ident"&gt;mysql&lt;/span&gt; &lt;span class="number"&gt;457&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;pgsql&lt;/span&gt; &lt;span class="number"&gt;581&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;mssql&lt;/span&gt; &lt;span class="ident"&gt;ado&lt;/span&gt; &lt;span class="number"&gt;9&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;mssql&lt;/span&gt; &lt;span class="ident"&gt;odbc&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;

&lt;span class="constant"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;:\&lt;/span&gt;&lt;span class="ident"&gt;home\app\bench\scripts&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ident"&gt;bench_db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;py&lt;/span&gt;
&lt;span class="ident"&gt;mysql&lt;/span&gt; &lt;span class="number"&gt;457&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;pgsql&lt;/span&gt; &lt;span class="number"&gt;578&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;mssql&lt;/span&gt; &lt;span class="ident"&gt;ado&lt;/span&gt; &lt;span class="number"&gt;9&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;mssql&lt;/span&gt; &lt;span class="ident"&gt;odbc&lt;/span&gt; &lt;span class="number"&gt;11&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;

&lt;span class="constant"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;:\&lt;/span&gt;&lt;span class="ident"&gt;home\app\bench\scripts&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ident"&gt;bench_db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;py&lt;/span&gt;
&lt;span class="ident"&gt;mysql&lt;/span&gt; &lt;span class="number"&gt;457&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;pgsql&lt;/span&gt; &lt;span class="number"&gt;581&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;mssql&lt;/span&gt; &lt;span class="ident"&gt;ado&lt;/span&gt; &lt;span class="number"&gt;8&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;mssql&lt;/span&gt; &lt;span class="ident"&gt;odbc&lt;/span&gt; &lt;span class="number"&gt;11&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;

&lt;span class="constant"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;:\&lt;/span&gt;&lt;span class="ident"&gt;home\app\bench\scripts&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ident"&gt;bench_db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;py&lt;/span&gt;
&lt;span class="ident"&gt;mysql&lt;/span&gt; &lt;span class="number"&gt;455&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;pgsql&lt;/span&gt; &lt;span class="number"&gt;641&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;mssql&lt;/span&gt; &lt;span class="ident"&gt;ado&lt;/span&gt; &lt;span class="number"&gt;9&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;
&lt;span class="ident"&gt;mssql&lt;/span&gt; &lt;span class="ident"&gt;odbc&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt; &lt;span class="ident"&gt;req&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Mit o rzekomej szybko&#347;ci MySQL ju&#380; jest nieaktualny. Nowy PostgreSQL 8 bije go pod ka&#380;dym wzgl&#281;dem. Zar&#243;wno wydajno&#347;ciowo i jak i znacznie wi&#281;kszymi mozliwo&#347;ciami (o tym mo&#380;e kiedy indziej).  Dziwi s&#322;aba, a raczej n&#281;dzna, wydajno&#347;&#263; produktu firmy Microsoft. Nie sprawdza&#322;em nowego &lt;span class="caps"&gt;MSSQL 2005&lt;/span&gt;, ale wszystko wskazuje na to, &#380;e przynajmniej &lt;span class="caps"&gt;MSSQL2K&lt;/span&gt; to kompletne dno!&lt;/p&gt;</description>
      <pubDate>Mon, 02 Apr 2007 17:14:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:43ae7c94-8984-4c09-86f1-fa0bf007d58c</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2007/04/02/postgresql-vs-mysql-vs-mssql2k</link>
      <category>mysql</category>
      <category>postgresql</category>
      <category>mssql</category>
      <category>benchmark</category>
    </item>
    <item>
      <title>Python vs. Ruby 1.9 YARV. Cz. II</title>
      <description>&lt;p&gt;Z &lt;a href="http://blog.zabiello.com/articles/2007/01/01/ruby-1.9-yarv"&gt;wcze&#347;niejszych test&#243;w&lt;/a&gt; wynika&#322;o &#380;e Ruby 1.9 (wykorzystuj&#261;cy wirtualn&#261; maszyn&#281; &lt;span class="caps"&gt;YARV&lt;/span&gt;) jest szybszy od Pythona.  Aby zwolennicy Rubiego zbyt si&#281; nie cieszyli, przygotowa&#322;em test na wywo&#322;ania rekurencyjne. Najci&#281;&#380;sz&#261; jest tu funkcja rekurencyjna. D&#322;ugo&#347;&#263; 7 znak&#243;w daje prawie 900 tys. wywo&#322;a&#324; rekurencyjnych i w miar&#281; sensowne czasy aby co&#347; zobaczy&#263;. Postanowi&#322;em j&#261; wzi&#261;&#263; na rozk&#322;ad. Tym razem z 10 pr&#243;b brany jest najlepszy (najkr&#243;tszy) wynik.&lt;/p&gt;


	&lt;h3&gt;Python:&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;try&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
  &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;psyco&lt;/span&gt;
  &lt;span class="ident"&gt;psyco&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;all&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
&lt;span class="ident"&gt;except&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
  &lt;span class="ident"&gt;pass&lt;/span&gt;

&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;wariancje&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;==&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
      &lt;span class="keyword"&gt;yield&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;
    &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
        &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;xrange&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;len&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;)):&lt;/span&gt;
            &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;c&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;wariancje&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
                &lt;span class="keyword"&gt;yield&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;]]&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;c&lt;/span&gt;
&lt;span class="ident"&gt;s&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;abcdefg&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="ident"&gt;nelem&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;len&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="ident"&gt;results&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;unused&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;range&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
  &lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
  &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;s&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;wariancje&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;nelem&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
    &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
  &lt;span class="ident"&gt;tmp&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;
  &lt;span class="ident"&gt;results&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;append&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;tmp&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;tmp&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;min&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;results&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; &lt;span class="ident"&gt;max&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;results&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; &lt;span class="ident"&gt;nelem&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Ruby&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;wariancje&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
    &lt;span class="keyword"&gt;yield&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;
  &lt;span class="keyword"&gt;else&lt;/span&gt;
    &lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;size&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;wariancje&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="keyword"&gt;yield&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;]]&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;c&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt;
&lt;span class="ident"&gt;s&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;abcdefg&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="ident"&gt;size&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;size&lt;/span&gt;
&lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="ident"&gt;results&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;
&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt;
  &lt;span class="ident"&gt;wariancje&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;size&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="ident"&gt;tmp&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;
  &lt;span class="ident"&gt;results&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;tmp&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;tmp&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="escape"&gt;\n&lt;/span&gt;&lt;span class="expr"&gt;#{results.min}&lt;/span&gt;, &lt;span class="expr"&gt;#{results.max}&lt;/span&gt;, &lt;span class="expr"&gt;#{size}&lt;/span&gt;, &lt;span class="expr"&gt;#{i}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Rezultat:&lt;/h3&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;strong&gt;Python 2.5&lt;/strong&gt;: 3.86356806755 s.&lt;/li&gt;
		&lt;li&gt;Python 2.4  4.09678792953 s.&lt;/li&gt;
		&lt;li&gt;Ruby 1.9:   6.418052 s.&lt;/li&gt;
		&lt;li&gt;Ruby 1.8.5: 8.000223 s.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Tym razem Python nie da&#322; szans Rubiemu. Jest od niego wyra&#378;nie szybszy. Jednak na obron&#281; mo&#380;na powiedzie&#263; &#380;e &lt;span class="caps"&gt;YARV&lt;/span&gt; nie jest tu jeszcze zbyt zoptymalizowany. Wiele opcji optymalizacyjnych ma po prostu wy&#322;&#261;czonych, Ruby 1.9 i &lt;span class="caps"&gt;YARV&lt;/span&gt; to na razie kod eksperymentalny. Na razie wi&#281;c dominacja wydajno&#347;ciowa Pythona jest niepodwa&#380;alna.&lt;/p&gt;</description>
      <pubDate>Sat, 06 Jan 2007 18:44:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:b2736448-f97e-4bd9-9824-e2899862a1da</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2007/01/06/python-vs-ruby-1-9-yarv-cz-ii</link>
      <category>python</category>
      <category>ruby</category>
      <category>yarv</category>
      <category>benchmark</category>
    </item>
    <item>
      <title>Ruby 1.9 (YARV) vs. Python, Lua &amp;amp; PHP</title>
      <description>&lt;p&gt;Korzystaj&#261;c z tego, &#380;e &lt;a href="http://redhanded.hobix.com/cult/yarvIsRubyItIsItReallyIs.html"&gt;niedawno do repozytorium Rubiego zosta&#322; dodany &lt;span class="caps"&gt;YARV&lt;/span&gt;&lt;/a&gt; (wirtualna maszyna Rubiego)  pokusi&#322;em si&#281; o ma&#322;e por&#243;wnanie wydajno&#347;ci. Jako test u&#380;y&#322;em prostego programu jaki &lt;a href="http://groups.google.com/group/pl.comp.lang.python/browse_thread/thread/61095f8a08ca5f9e/1646948032dc08c0?lnk=st&amp;#38;q=&amp;#38;rnum=2&amp;#38;hl=pl#1646948032dc08c0"&gt;pojawi&#322; si&#281; na li&#347;cie pl.comp.lang.pyhon&lt;/a&gt; (musia&#322;em tylko troch&#281; zwi&#281;kszy&#263; p&#281;tle do 10 milion&#243;w iteracji, aby by&#322;y widoczne jakie&#347; wyniki) U&#380;yty sprz&#281;t: Athlon64 3700+, 64bit Ubuntu 6.0.6.&lt;/p&gt;


	&lt;p&gt;Sprawdzi&#322;em te&#380; z ciekawo&#347;ci &lt;span class="caps"&gt;PHP 5&lt;/span&gt;.2 na tym samym sprz&#281;cie. Dla tak prostego testu powinien m&#243;c da&#263; z siebie wszystko. Jest jednak wolniejszy od Rubiego 1.9.&lt;/p&gt;


	&lt;p&gt;Kod dla Pythona:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;
&lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;xrange&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;10000000&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
    &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Kod dla Lua:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;clock&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
&lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="number"&gt;10000000&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;+&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;clock&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Kod dla Rubiego:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt;
&lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;..&lt;/span&gt;&lt;span class="number"&gt;10_000_000&lt;/span&gt;
  &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;+&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Kod dla &lt;span class="caps"&gt;PHP&lt;/span&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_php "&gt;&amp;lt;?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 &amp;lt; 10000000; $i++) {
  $a += $i;
}
print &amp;quot;$a\n&amp;quot;;
print  microtime_float()- $t;
?&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Wyniki:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Lua: 1.14 s&lt;/li&gt;
		&lt;li&gt;Ruby 1.9: &lt;strong&gt;1.49 s&lt;/strong&gt;&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;PHP 5&lt;/span&gt;.2: 1.74 s&lt;/li&gt;
		&lt;li&gt;Python 2.5: 2.64 s&lt;/li&gt;
		&lt;li&gt;Python 2.4.3: 2.72 s&lt;/li&gt;
		&lt;li&gt;Ruby 1.8.5: 3.83 s.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h2&gt;Drugie podej&#347;cie&lt;/h2&gt;


	&lt;p&gt;Tym razem wynik u&#347;redniam dla 10 pr&#243;b. Zwi&#281;kszy&#322;em ilo&#347;&#263; iteracji do &lt;strong&gt;20 mln&lt;/strong&gt;. No i&amp;#8230; Ruby 1.9 pobi&#322; wszystko. Zar&#243;wno Pythona jak i Lua! (PHP 5.2 po 30 sek. zg&#322;osi&#322; timeout. Musia&#322;em wi&#281;c u&#347;redni&#263; po 5 wynikach.)&lt;/p&gt;


	&lt;h3&gt;&lt;span class="caps"&gt;PYTHON&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;bench&lt;/span&gt;&lt;span class="punct"&gt;():&lt;/span&gt;
    &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
    &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;xrange&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;20000000&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
        &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;+=&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()-&lt;/span&gt;&lt;span class="ident"&gt;t&lt;/span&gt;
&lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;range&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
  &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;bench&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="number"&gt;10.0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;&lt;span class="caps"&gt;RUBY&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;bench&lt;/span&gt;
  &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt;
  &lt;span class="number"&gt;20_000_000&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;bench&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;&lt;span class="caps"&gt;LUA&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_lua "&gt;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)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_php "&gt;&amp;lt;?php
function bench() {
  $a = 0;
  $t =  time();
  for ($i = 0; $i &amp;lt; 20000000; $i++) $a += $i;
  return time() - $t;
}
$result = 0;
for ($x = 1; $x &amp;lt;= 5; $x++) $result += bench();
print $result / 5.0;
?&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Wyniki&lt;/h3&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;strong&gt;Ruby 1.9:       2.0953268 s.&lt;/strong&gt;&lt;/li&gt;
		&lt;li&gt;Lua 5.1:        2.4 s.&lt;/li&gt;
		&lt;li&gt;Python 2.5:     2.49481592178 s.&lt;/li&gt;
		&lt;li&gt;Python 2.4.3:   2.71687791348 s.&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;PHP 5&lt;/span&gt;.2:        4.2 s.&lt;/li&gt;
		&lt;li&gt;Ruby 1.8.5:     9.0153751 s.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Jestem ciekaw kiedy wyjdzie &lt;a href="http://i.loveruby.net/d/20060220.html#p10"&gt;Rails dostosowany do Ruby 1.9&lt;/a&gt;. Zapowiada si&#281; bardzo obiecuj&#261;co!&lt;/p&gt;</description>
      <pubDate>Mon, 01 Jan 2007 19:36:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:195b9e84-80ff-47b9-a2ae-38070f3da6f0</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2007/01/01/ruby19-yarv</link>
      <category>PHP</category>
      <category>Python</category>
      <category>Ruby</category>
      <category>lua</category>
      <category>python</category>
      <category>ruby</category>
      <category>php</category>
      <category>yarv</category>
      <category>benchmark</category>
    </item>
  </channel>
</rss>
