Srovnání rychlostí volání PHP funkcí a metod

in Web, Informatika, PHP
php.png

Nedávno jsem stál před problémem, jaký styl programování v PHP zvolit, pokud bych chtěl zohlednit rychlost provádění kódu. Zejména mě zajímalo, jak jsou rychlé třídní/instanční metody oproti přímému volání funkcí a zda-li došlo v novější verzi PHP k nějakému posunu v použitelnosti objektového stylu programování (OOP).

PHP obecně má, krom mnoha jiných, jednu velkou nevýhodu a tou je znovuspouštění skriptů při přijetí nového HTTP požadavku (vše se sestavuje znovu). Existují však programovací jazyky, jako například Python nebo Java, které mohou fungovat na principu aplikačního serveru (WSGI, Tomcat). To zjednodušeně řečeno znamená, že webová aplikace "běží" jako klasický program, ve kterém se při přijetí nového HTTP požadavku zavolá k tomu určená obslužná rutina (handler, vstupní bod). Nemusí se ale znovuspouštět celá webová aplikace (jako např. inicializací spojení s DB, session, cache atp).

Při pátrání na internetu jsem nalezl zajímavá čísla z roku 2006, která srovnávají časovou náročnost volání funkcí a metod v PHP. Pro názornost jsem sestavil následující graf:

Jelikož jsem nepřišel na způsob jak otočit pořadí jednotlivých položek v grafu, prosím laskavé čtenáře o čtení zdola nahoru :) Zajímají nás především nuance mezi jednotlivými způsoby volání, nikoliv čas samotný.

Graf představuje nezbytný čas v sekundách, který byl zapotřebí pro dokončení 1 000 000 volání. CUF přitom znamená dynamické volání pomocí funkce call_user_func() a CUFA znamená dynamické volání pomocí call_user_func_array().

Z grafu lze vypozorovat, že nejlépe je na tom volání statické metody přímou cestou, nejhorším případem je volání statické metody pomocí funkce call_user_func. Je třeba mít ale na zřeteli, že se jedná o výsledky z roku 2006!

Výsledky z roku 2011 a PHP ve verzi 5.3 jsou následující:

Zásadní rozdíly oproti starší verzi (patrně 5.0) lze shrnout do těchto bodů:

  • nejlépe je na tom přímé volání funkce,
  • v těsném závěsu stojí dynamické volání funkce pomocí proměnné a volání metody třídy (cca stejně rychlé),
  • statické volání je cca dvakrát pomalejší než přímé volání,
  • nejhorší je volání funkcí call_user_func a úplná noční můra je call_user_func_array.

Z výsledků je patrné, že se vyplatí používat OOP aniž by docházelo ke zpomalení skriptů. Rozhodně se ale nevyplatí dynamické volání pomocí výše zmíněných funkcí. Pokud to je možné, nahraďte je voláním přes proměnnou:

function pozdrav() {
   print "ahoj";
}

$fce = 'pozdrav';
$fce(); // vyrazne rychlejsi nez call_user_func('pozdrav');

Pokud se stále neumíte rozhodnout, zkuste se podívat ještě zde :)