Zend Framework to oczywiście najlepszy framework php ;) ale ma bardzo duże problemy co do wydajności. Przy prostych stronach można to jeszcze przeżyć, ale dla aplikacji, które są przewidziane na duże obciążenie staje się to już drzazgą w tyłku.
Na pierwszy ogień pójdzie funkcja Zend_Loader::registerAutoload() - korzystanie z niej jest bardzo wygodne, ale wpływa bardzo negatywnie na szybkość i ilość pamięci wykorzystywanej przez skrypt.
Przeprowadźmy test
Aby test miał więcej wspólnego z rzeczywistością zostanie wykonany na już przygotowanym frameworka do pracy. Z grubsza będą to:
- Inicjacja i sprawdzenie autoryzacji na podstawie Zend_Acl (lista praw trzymana w pliku php)
- Wykryciu i ustawieniu odpowiedniego locale (Zend_Locale)
- Ustawienia widoku
- Nawiązanie połączenia z bazą danych MySql
- Ustawieniu routes na podstawie plików ini
- Inicjacji Zend_Mail_Transport_Smtp
Akcja indexAction() jest pusta, nie jest wykonywane żadne zapytanie do bazy danych. Do profilowania kodu użyłem zmodyfikowanego Profiler’a z Magento Ecommerce. Kod został podzielony na odpowiednie bloki: application, setup, dispatch, action. Na mojej maszynie mam:
- PHP 5.2.4
- XDebug 2
- Apache 2
- MySql 5
Samych parametrów mojego komputera nie będę podawał, bo nie ma to sensu, nie będziemy zwracać uwagi na same liczby, a raczej na różnice procentowe.
Nas najbardziej interesuje pierwszy rząd ‘Application’ obejmująca całą aplikacje. Najbardziej przykuwającą oko rzeczą jest pożerana pamięć 5MB.
Teraz przygotujemy plik require.php, który dołączamy jak najwcześniej w bootstrapie. Plik zawiera dołączenia wszystkich klas aplikacji (Zend i nasze własne), które były potrzebne do uruchomienia strony testowej.
require_once 'Zend/Session.php';
require_once 'Zend/Session/Abstract.php';
require_once 'Zend/Session/Namespace.php';
require_once 'Zend/Session/SaveHandler/Interface.php';
require_once 'Zend/Session/Exception.php';
require_once 'Zend/Exception.php';
require_once 'Zend/Acl/Role/Interface.php';
require_once 'Zend/Config.php';
itd...
Pomimo prawie 3-krotnie zmniejszonego czasu (0.25 vs 0.09), pamięć wykorzystana przez skrypt zmalała z 5 MB do 326 KB, to ponad 10-krotnie mniej!!! Nawet sobie nie wyobrażacie jaka to ulga dla serwer.
Listę plików ładowanych podczas działania aplikacji można otrzymać dzięki informacji jakie klasy zostały załadowane (w ZF jedna klasa to jeden plik), a tę informacje dostajemy dzięki funkcji get_declared_classes().
Wniosek
Na etapie tworzenia aplikacji spokojnie możemy ze względu na wygodę używać Zend_Loader::registerAutoload(), zaś już w czasie wdrażana zdecydowanie sugeruję rozwiązanie podobne do mojego.
Dodaj mój rss to swojego czytnika.



Sunday, November 9, 2008 5:47 pm
Warto dodać, iż w pliku require.php najlepiej dodać tylko te pliki, które są wykorzystywane przy każdym (lub w większości przypadku) żądaniu. Jeżeli zaincludujemy wszystkie to znowu możemy mieć małą nadmiarowość ;).
Część plików można oczywiście też includować ręcznie ;)
PS. Gratuluje determinacji i powrotu do pisania na blogu ;)
Thursday, July 10, 2008 7:50 pm
Na jakiej wersji Zend Frameworka był przeprowadzany test? Jeżeli dobrze pamiętam w 1.6 zostały wprowadzone poprawki do Zend_Loader’a. Sprawdziłem przez get_declared_classes(), uzyskane wyniki prze użyciu Zend_Loadera jak i przy require’owaniu poszczególnych klas były identyczne.
Thursday, July 10, 2008 10:01 pm
@PE Dobra uwaga. Testy były przeprowadzone na wersji 1.5.1. Będę musiał uzupełnić wpis. Przy okazji jeżeli porównujemy poszczególne wersje, to wydajność ZF z czasem spada. Porównaj np. wersje 1.0.1 z 1.6.
Sunday, August 10, 2008 10:06 am
Z braku innych narzędzi sprawdziłem pamięć przez memory_get_usage() przyznam się że wynik troszkę mnie zaskoczył:
bez autoloadera: 4644968
z autoloaderem: 4642872
A co do wydajności … to wszystko zależy od tego jak się do sprawy podchodzi i co chcemy uzyskać ;)
Może warto było by dodać małą adnotację jakieś wersji dotyczy tekst ?
Sunday, August 10, 2008 1:29 pm
Tak, dodam adnotacje i zrobie update postu. Narazie nie mam czasu :/
Sunday, May 11, 2008 8:28 am
W nowszych wersjach jeszcze lepsze wyniki może dac pozostawienie autoloadera i usunięcie we wszystich plikach ZF wywołań instrukcji require_once. Z tego co wiem to w przyszłości ma się pojawić w komponencie Zend_Tool narzędzie ułatwiające usuwanie.
Sunday, May 11, 2008 12:47 pm
Między innymi o tym i innych sposobach przyspieszenia ZF można przeczytać tutaj
Saturday, October 11, 2008 10:01 am
[…] Pierwsze linijki ładują plik konfiguracyjny oraz klasy usług. Korzystam z Zend_Loadera, ponieważ przyspiesza on pisanie, ale oczywiście ma on wpływ na wydajność aplikacji o czym więcej możesz dowiedzieć tutaj DzbanyIT. […]