Webdesignérská komunita se asi shodne na tom, že nejrychlejší implementace
PHP pro Apache, z možností CGI, FastCGI a modulu,
by měl být právě modul, protože PHP modul pro Apache je psán
pro nativní API Apache 2.0 serveru. Odtud tedy ona rychlost…
CGI naopak v teorii znamená, že CGI skript musí při každém použití PHP vyhledat
a parserovat php.ini,
spustit php-cgi.exe a natahovat spousty dll knihoven (extensions).
To je pomalé, nicméně, vzhledem k tomu, že jsou stejně všechny dll knihovny
v RAM paměti, a vzhledem k výkonu testovacího stroje (3.2GHz Pentium-4/HT
procesor, 1GB RAM), nebude to zpoždění až tak zásadní.
FastCGI ovšem CGI zlepšuje v tom, že při startu Apache serveru spustí definovaný
počet php-cgi.exe procesů v paměti a nechá je běžet po celou dobu,
a při požadavku na PHP interpret jim tento dotaz předá ke zpracování.
Tolik tedy teorie. Rozhodl jsem se v praxi otestovat, jak je Apache/PHP kombo
rychlé v reálném provozu v režimech CGI, FastCGI a modul.
Testoval jsem funkci, která 1000x za sebou provede vytvoření dlouhého řetezce
znaků. Práce s textem je základem PHP.
Funkce vypadala takto:
function test(){
$s='';
for ($i=0; $i<200; $i++) $s.=strval($i).' ';
}
$timer = & new Timer();
$test = & new Statistics('Module');
$iterationsCount = 10;
$subIterationsCount = 1000;
// stress test
@set_time_limit(1200);
for($i = 0; $i < $iterationsCount; $i++) {
$timer->start();
for($j = 0; $j < $subIterationsCount; $j++) test();
$test->add($timer->stop());
}
Výsledky popsané slovně:
Jaké jsou výsledky? No, velice překvapivé. Zvítězilo, dle očekávání, FastCGI.
Nejenže má FastCGI nejrychlejší čas, ale rovněž nejmenší standardní odchylku.
Je vidět, že procesy běžící na pozadí a bez přerušení Windows XP zjevně vyhovují.
Nicméně, při testu jsem se setkal s jedním "zamrznutím" FastCGI, pomohl
až restart Apache serveru (a tím i FastCGI), zřejmě toto řešení není vhodné
pro produkční servery. Alespoň ne na Windows. Při použití Apache/PHP jako
modulu či CGI jsem se se "zamrznutím" nikdy nesetkal.
Udělám ještě stejný test na Linuxu, ovšem zde bude FastCGI kompilované ze
zdroje, uvidíme, jak na tom bude rychlost a stabilita.
Mnohem překvapivější už ovšem je pořadí mezi CGI a modulem. Modul má být v
teorii rychlejší, CGI je považováno za cosi méněcenného. Ale není.
CGI bylo o několik procent rychlejší než modul, přičemž modul měl i nejvyšší
standardní odchylku ve výkonu.
Pokud tedy děláte vývoj na lokální stanici, a potřebujete PHP4 i PHP5, což
se dá dělat jen přes CGI, či FastCGI, klidně je použijte. Rovněž, pokud má Vaše
stanice málo paměti, CGI bude lepší řešení než modul, nebo dokonce než FastCGI,
které zabírá neustále RAM a systémové zdroje, zatímco CGI je používá jen nárazově.
Za zvážení v tomto testu by stálo, zda PHP modul pro Apache nebyl v
mém počítači s Pentium-IV/HT limitován jen na jeden virtuální procesor, zatímco
CGI a FastCGI běželo na jednom z virtuálních CPU a Apache (jako jiný proces)
na druhém CPU. To by vysvětlovalo výkonnostní propad modulu, neboť měl k
dispozici jen jedno CPU, zatímco CGI a FastCGI versus Apache oba dva.
Nicméně, jednoprocesorovou stanici (ne-HT) nemám, abych tuto hypotézu ověřil.
Výsledky v číslech:
| PHP |
Průměr |
STD |
| FastCGI |
0.193922 s |
0.003849 |
| CGI |
0.201782 s |
0.005289 |
| Modul |
0.206030 s |
0.008616 |
Konfigurace httpd.conf:
## GENERAL PHP CONFIG
ScriptAlias /php/ "C:/dev/prog/php/"
DirectoryIndex index.html index.htm index.php
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
## MODULE
#LoadModule php5_module "c:/dev/prog/php/php5apache2.dll"
## CGI
#Action application/x-httpd-php "/php/php-cgi.exe"
## FastCGI
LoadModule fastcgi_module "c:/dev/prog/php/ext/mod_fastcgi.dll"
FastCgiServer "C:/dev/prog/php/php-cgi.exe" -processes 2
Action application/x-httpd-fastphp "/php/php-cgi.exe"
AddType application/x-httpd-fastphp .php
Chtěl bych zdůraznit, že dané závěry se vztahují na jednu vysoce výkonnou
pracovní stanici s Windows XP, nikoliv na použití na web-hostingu, kde je potřeba
brát do úvahy rovněž další faktory.
Použité komponenty:
- Apache 2.0.52,
- FastCGI 2.4.2 pro Apache 2.0,
- PHP 5.0.2,
- Windows XP SP2.
Pochopil jsem to správně, že jste spustil jeden požadavek z klienta, proběhlo 1000 měření v cyklu, vyběhlo 1000 časů a to je vše? Při tomhle zbůsobu měření není důvod, aby byly velké rozdíly mezi jednotlivými moduly velké. Hlavní zpoždění CGI je v načítání .exe, parsování php.ini a tak, ale to v tohle měření není vůbec zahrnuto, měří se pouze jednotlivé cykly výpočtu. Stejně tak komunikace s apachem proběhne až za koncem celého měření při výpisu výsledků, takže ani to by nemělo mít vliv.
Jsou nekde k dispozici Timer a Statistics tridy, at se to muze pustit i jinde?
[1] vtip je v tom, že ono CGI nemá oproti modulu v praxi zpoždnění.. naopak na mé konkrétní konfiguraci bylo rychlejší, a nejlépe na tom bylo FastCGI, dle očekávání..
[2] dám je na web, prvně ale udělám ještě podobný test pro Linux
[3] Viditelné zpoždění nemá, to je pravda, takže pro ladění je CGI dobře použitelné a má i své výhody (zejména při zkoušení míň stabilních částí PHP nebo hledání správného modulu není nutné každou chvíli restartovat apache). Přesto jsem přesvědčen, že pomalejší spuštění se CGI nepovede u většiny stránek dohnat rychlejším během.
Proč je CGI v běhu rychlejší, než modul je taky zajímavé. Moje teorie je, že by to mohlo být způsobeno alokací paměti, která u modulu pravděpodobně (do zdrojáků jsem nekoukal) musí projít přes funkce apache.
Technologii HT lze vypnout v BIOSu, ale to jistě víš.
[1] Pokud byl test proveden skutečně takto (a zveřejněný skript tomu napovídá), tak to opravdu nedává smysl. Největší ztráta CGI přeci bude před spuštěním a ne během něj. Smysl by dával test, který provede 1000 stažení skriptu (nebo lépe střídavě více různých skriptů) a vypíše celkový čas.