Pliki konfiguracyjne w Zend Framework vs wydajność
Napisane: 21.02.2009 | Działy: PHP | 6 CommentsTagi: PHP, Zend Framework
W końcu zabrałem się za pisanie pisanie stronki dla firmy mojego taty. Zdecydowałem się postawić ją na Zendzie i troszkę poeksperymentować ;) Dziś postanowiłem porównać wydajność konfiguracji zapisanej w pliku INI oraz w pliku PHP jako gotowa tablica.
Testowałem aplikację typu Hello World + ładowanie konfiguracji + wrzucanie ścieżek do routera (12 ścieżek). Pliki konfiguracyjne ini i php oraz pliki ze sposobem uruchamiania Zenda zamieszczam na końcu wpisu.
Testy zostały przeprowadzone lokalnie (PHP 5.2.8) i na zdalnym serwerze (PHP 5.2.6). Wyniki testu dały mi do myślenia…
Wyniki testów lokalnych
-
Complete requests: 1000
-
Failed requests: 0
-
Keep-Alive requests: 991
-
Total transferred: 625596 bytes
-
HTML transferred: 345000 bytes
-
Requests per second: 32.20 [#/sec] (mean)
-
Time per request: 31.055 [ms] (mean)
-
Complete requests: 1000
-
Failed requests: 0
-
Keep-Alive requests: 991
-
Total transferred: 625596 bytes
-
HTML transferred: 345000 bytes
-
Requests per second: 35.09 [#/sec] (mean)
-
Time per request: 28.495 [ms] (mean)
Wyniki testów na serwerze
-
Complete requests: 10000
-
Failed requests: 0
-
Keep-Alive requests: 9901
-
Total transferred: 6525546 bytes
-
HTML transferred: 3450000 bytes
-
Requests per second: 33.22 [#/sec] (mean)
-
Time per request: 30.104 [ms] (mean)
-
Complete requests: 10000
-
Failed requests: 0
-
Keep-Alive requests: 9901
-
Total transferred: 6525546 bytes
-
HTML transferred: 3450000 bytes
-
Requests per second: 36.44 [#/sec] (mean)
-
Time per request: 27.441 [ms] (mean)
Wyniki są podobne na obu maszynach. Różnica około 3req/sec na korzyść plików PHP daje nam to około 8% różnicy w czasach wykonywania się. Dodatkowo chciałem zauważyć że ilość danych w plikach była stosunkowo niewielka (konfiguracja połączenia z bazą + 12 ścieżek) i prawdopodobnie dla większych plików konfiguracyjnych różnica czasów może jeszcze wzrosnąć.
Wyniki są dla mnie trochę zaskakujące, ponieważ składnia plików INI jest dużo prostsza i ich parsowanie powinno być szybsze. Być może opóźnienie wiąże się to z narzutem związanym z klasą Zend_Config_Ini i używaniem funkcji __get podczas pobierania danych z obiektu konfiguracyjnego. Z drugiej strony załadowanie konfiguracji do kontrolera także wymaga utworzenia obiektu klasy Zend_Config.
Co Wy sądzicie na ten temat?
EDIT
Po komentarzu scannera nie mogłem wytrzymać do następnego dnia i przeprowadziłem dodatkowy test. ;) Składał się on z 2 bardzo prostych skryptów, które miały mierzyć czas parsowania pliku INI i dołączanie gotowej tablicy. Ich kod wyglądał tak:
-
require 'config.php';
-
$aConfig = parse_ini_file( 'config.ini', true );
Wyniki pomiarów są zgodne z moimi oczekiwaniami:
-
Complete requests: 10000
-
Failed requests: 0
-
Keep-Alive requests: 9901
-
Total transferred: 2785546 bytes
-
HTML transferred: 0 bytes
-
Requests per second: 1681.33 [#/sec] (mean)
-
Time per request: 0.595 [ms] (mean)
-
Complete requests: 10000
-
Failed requests: 0
-
Keep-Alive requests: 9901
-
Total transferred: 2785546 bytes
-
HTML transferred: 0 bytes
-
Requests per second: 1818.92 [#/sec] (mean)
-
Time per request: 0.550 [ms] (mean)
Tym razem parsowanie plików INI jest o 8% wydajniejsze od parsowania kodu PHP (tak na marginesie muszę przyznać, że parser PHP to szybka bestia).
Podsumowując.
Parsowanie konfiguracji zapisanej w pliku ini przez Zend Framework dość mocno spowalnia ten proces. Prawdopodobnie problem leży w bardzo ofensywnym programowaniu deweloperów tego frameworka (ustawianie własnych error hendlerów, sprawdzanie wszystkiego na około itp.) i dodatkowych zabiegach wykonywanych na tablicy zwróconej przez funkcję parse_ini_file.
Jeżeli piszesz dużą aplikację, która jest mocno obciążona i liczy się dla ciebie każda milisekunda spróbuj przetestować przeniesienie configa do pliku php z gotową tablicą. Może uda Ci się wycisnąć kilka dodatkowych requestów.



Komentarze
6 Comments Dodaj komentarzNo dobrze, ale tablice php są bardziej natywne, niż pliki INI – te bowiem muszą przejść przez dodatkowy parser IMHO.
Nie zgodzę się z Tobą tak do końca. Pliki ini przechodzą przez parser dużo prostszy niż kod PHP i powinny być parsowane szybciej.
Jutro wykonam jeszcze test parsowania tablicy i pliku ini bez udziału zenda, bo w nim może leżeć problem.
Z tego co pamiętam jeszcze szybsze od PHP/INI jest unserialize + file_get_content, mógłbyś to do testu podpiąć – wtedy przetrzymywanie konfiguracji w PHP lub INI, jednokrotne zapisanie ich w serialize i tylko szybki odczyt.
Z tego co pamiętam to parsowanie plików ini odbywa się PRZED “uruchomieniem” samego parsera samego php’a, dlatego zawsze będzie on wydajniejszy niż tablice hashowane.
Swoją drogą ciekawe jak wyglądał by wynik przy wykorzystaniu SplFastArray dla 5.3 ;) (choć IMO pewnie nie zdąży “wejść” do wersji 5.3.0 ^^)
“Jeżeli piszesz dużą aplikację, która jest mocno obciążona i liczy się dla ciebie każda milisekunda (…)” nie używaj Zend Framework :)
Nie zgodzę się z Tobą. Pisanie frameworka od zera to odkrywanie koła na nowo, trzeba bazować na sprawdzonych rozwiązaniach i ewentualnie modyfikować je do swoich potrzeb.