Autor wpisu: Marek, dodany: 24.10.2012 22:38, tagi: php, zend_framework
Zend Framework ma to do siebie, że gdy obejrzymy zawartość plików jego biblioteki, zauważymy, że nagminnie korzysta z require_once. Pomimo, że wyrażenie to zabezpiecza przed ponownym załadowaniem tego samego pliku do pamięci, to rozwiązanie ma swoje wady wydajnościowe. Za każdym razem, gdy parser PHP napotyka na swojej drodze require_once, czesze po dysku celem sprawdzenia czy dany plik istnieje. Nieważne, że ten plik został chwilę wcześniej załadowany do pamięci.
W przypadku, gdy w aplikacji opartej o zf używamy autoloadera, choćby poprzez wywołanie:
require_once 'Zend/Loader/Autoloader.php'; Zend_Loader_Autoloader::getInstance();
możemy zakomentować wszystkie wystąpienia w bibliotece Zenda wyrażenia require_once. Służy do tego np. zgrabna komenda:
cd /path/to/ZendFramework/library find . -name '*.php' -not -wholename '*/Loader/Autoloader.php' \ -not -wholename '*/Application.php' -print0 | \ xargs -0 sed --regexp-extended --in-place 's/(require_once)/\/\/ \1/g'
Żeby nie być gołosłownym zrobiłem prosty test programem Apache Benchmark wywołując 10 tysięcy razy aplikację lokalnie utworzoną poprzez
zf create project zf-stat .
Po podlinkowaniu biblioteki frameworka wywołałem dwukrotnie polecenie:
ab -n 10000 localhost/stat-zf/public
Najpierw na „gołej” instancji Zend Framework 1.12.0, za drugim razem po zakomentowaniu require_once w bibliotece.
Zend Framework 1.12.0 z require_once:
Time taken for tests: 2.725 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Non-2xx responses: 10000 Total transferred: 5700000 bytes HTML transferred: 3150000 bytes Requests per second: 3669.87 [#/sec] (mean) Time per request: 0.272 [ms] (mean) Time per request: 0.272 [ms] (mean, across all concurrent requests) Transfer rate: 2042.80 [Kbytes/sec] received
Zend Framework 1.12.0 bez require_once:
Time taken for tests: 2.003 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Non-2xx responses: 10000 Total transferred: 5700000 bytes HTML transferred: 3150000 bytes Requests per second: 4992.42 [#/sec] (mean) Time per request: 0.200 [ms] (mean) Time per request: 0.200 [ms] (mean, across all concurrent requests) Transfer rate: 2778.98 [Kbytes/sec] received
Jak widać już przy tak trywialnym teście czas jego trwania wzrósł prawie o połowę, żądania wzrosły z liczby 3669.87 do 4992.42, średni czas żądania spadł z 0.272 ms do 0.200 ms, a transfer wzrósł z 2042.80 [Kbytes/sec] do 2778.98 [Kbytes/sec].