Chciałbym na własnej skórze przekonać się jak ma się wydajność Zend_Framework + phpDoctrine (orm) do wydajności ROR-a.
Postanowiłem więc napisać dwie lustrzane aplikacje w obu frameworkach, które będą robić dokładnie to samo.
W skrócie ma to być jeden kontroler i jedna akcja. W akcji tej będę chciał wielokrotnie zapisać jakieś dane do bazy, odczytać je i wygenerować widok.
Myślałem jeszcze o operacjach na dużym drzewku Nested Set - oba orm-y mają odpowiednie pluginy.
Co jeszcze powinienem wziąć po uwagę by bechmark ten był jak najbardziej obiektywny?
Wydajność chcę zmierzyć najprostszym możliwym sposobem - ab z kombinacją różnych parametrów.
ROR-a chcę przetestować dla różnych konfiguracji - Mongrel, moduł Apache, FastCGI, WebRick.
Nie zapomnij odpalić railsów w trybie production. Mam nadzieję, że testujesz pod linuksem? Dobrze by było użyć kompilowanych wersji zarówno rubiego jak i php (ruby z paczek lubi być sporo wolniejszy od kompilowanego). W zależności od ilości równoczesnych requestów możesz spróbować z kilkoma mongrelami. WebRick możesz sobie darować.
Dobrze by bylo tez przetestowac rails z kilkoma instancjami mongrela. Chyba ze jestes wstanie odpalic zend framework i doctrine tylko na jednym procesie. Wtedy test 1:1.
Dlaczego interesuje Cię wydajność? Ani Ruby, ani Railsy nie były i nie są optymalizowane pod kątem wydajności. Co autorzy podkreślają średnio raz na dwa tygodnie
Ktoś już kiedyś robił benchmark Symphony vs. Rails vs. Django i wyszło, że Django jest najszybsze. To było dawno temu i dużo się od tego czasu zmieniło. Fajnie byłoby zobaczyć nowe wyniki chociaż szczerze mówiąc te mikro benchmarki oprócz trafiania na Digg’a i robienia dobrego/złego PR nie przedstawiają “real world usage”. Co z tego że np. w Django w benchmarku na 1 akcji dostaniesz 900 reqs/s w Rails 700 w Symphony tylko 500? User tego i tak nie zauważy. Zauważy natomiast jeśli Twoja baza ma 20 milionów rekordów czy 200 milionów i zaczyna zwalniać i masz średnio 0.5 reqs/s - ale o tym niewiele osób pisze bo skalowanie bazy/search engin’a to temat zbyt skomplikowany, niewiele osób się na tym zna no i ew. artykuł nie zrobi szumu na Digg’u bo to o bazie i w ogóle nudy
Podobnie jest z mikro benchmarkami web serwerów, Ebb 2000 reqs/s, Thin 1000, Mongrel 800 - Wow. wybieram Ebb bo jest najszybszy Give me a break, jakie to ma znaczenie ???
Zrobiłem proste testy i wyszło mi, że z wydajnością Rails (2.0) nie jest wcale tak źle.
php uruchomione bez dodatków (np bez Zend Debugger, XDebug), baza - postgres
ROR uruchomiony na mongrelu w trybie developerskim, Ruby, gem, rails zainstalowane z paczek Ubuntu
test nr.1
Hello World - akcja generująca napis hello world, brak połączenia z bazą, prosty layout strony
ab -c 2 -n 1000
ZF: Requests per second: 18.56 [#/sec] (mean)
ROR: Requests per second: 32.73 [#/sec] (mean) !!!
test nr.2
Testowanie takiego oto kodu
(proszę zwrócić uwagę na seksowność kodu rubiego i siermiężność php… prowokacja ):
[code] def test1
100.times do |i|
record = Record.new
record.title = 'test'
record.content = 'test'
record.value = i
record.save
end
@records = Record.find :all, :limit => 100, :order => 'RANDOM()'
@records.each do |record|
record.title = 'test1'
record.content = 'test1'
record.save
end
end
public function test1Action()
{
for ($i = 0; $i < 100; $i++) {
$record = new Record();
$record->title = 'test';
$record->content = 'test';
$record->value = $i;
$record->save();
}
$records = Doctrine_Query::create()
->from('Record r')
->orderBy('RANDOM()')
->limit(100)
->execute();
foreach ($records as $record) {
$record->title = 'test1';
$record->content = 'test1';
$record->save();
}
$this->view->records = $records;
}[/code]
- wyświetlenie w widoku 100 losowo pobranych rekordów
ab -c 2 -n 1000
ZF: Requests per second: 1.27 [#/sec] (mean)
ROR: Requests per second: 0.86 [#/sec] (mean)
test nr.3
Pobranie z bazy i wyświetlenie 100 wybranych rekordów
ab -c 2 -n 1000
ZF: Requests per second: 2.61 [#/sec] (mean)
ROR: Requests per second: 1.53 [#/sec] (mean)
…spodziewać się chyba można, że Rails uruchomiony na produkcyjnym i dobrze skonfigurowanym serwerze jest w stanie pobić Zend Framework
No to odpal w trybie produkcyjnym i sprawdź (ruby script/server -e production). W czym problem?
Zrób po 12 iteracji na każdej konfiguracji. Odrzuć dwa najgorsze i dwa najlepsze wyniki - resztę uśrednij. Taką technikę stosuje się w środowiskach których nie można kontrolować w 100% i mogą się pojawić inne czyniki (np.: inne procesy chodzące na tej maszynie).