PHP přineslo ve své sedmé major verzi velmi zásadní zrychlení a snížení spotřeby paměti.
Podle některých benchmarků je nyní PHP při řešení některých úloh o dost rychlejší než Python 3.
Jak je na tom PHP ve své domovské oblasti, tedy na webu?
Je i tady výhodnější z pohledu výkonu použít PHP?
Metodika testu
Nebudeme měřit jen Hello world, pro náš malý test si vytvoříme "microservice", která přijme číslo a vrátí odpovídající prvek ve Fibonacciho posloupnosti.
Nebudeme stavět na zelené louce, využijeme populární frameworky ze světa PHP i Pythonu.
Díky tomu prověříme více vlastností platformy najednou:
- rychlost startu aplikace
- rychlost frameworku
- hrubý výpočetní výkon jazyka - rychlost rekurzivního volání a sčítání
- rychlost renderování šablon
Pro všechny testované aplikace si pustíme v jednom procesu Nginx, který bude požadavky předávat backendu přes FastCGI a WSGI.
PHP aplikace poběží jako PHP-FPM ve čtyřech procesech. Python aplikace poběží jako UWSGI také ve čtyřech procesech.
Zátěž budeme generovat pomocí nástroje Apache Bench.
Pro každý testovaný případ pošleme 100 HTTP dotazů, v 10 souběžných spojeních.
Výsledky
Konec řečí, ukaž čísla!
První číslo Fibonacciho řady je PHP s Nette schopno naservírovat 600x za sekundu.
Slim, který je trochu minimalističtější než Nette, pak téměř 2x tolik.
Python 3 s Flaskem tady ale PHP jasně válcují a stihnou vrátit výsledků víc než dvakrát tolik co Slim. Je to pravděpodobně proto, že UWSGI startuje aplikaci pouze jednou na začátku (vytvoří objekt application) a při dalších požadavcích už jen volá její metody. Naproti tomu FastCGI vytváří aplikaci při každém požadavku znovu.
U 18. čísla Fibonacciho řady se situace začíná pomalu obracet.
Slim i Flask zvládají vyřídit tisíc požadavků.
Vývojářům PHP se zrychlení opravdu podařilo, a tak čím víc aplikace počítá, tím se PHP posouvá před Python.
U 30. čísla je rozdíl už opravdu markantní, PHP upočítá 23 dotazů, zatímco Python pouze 4.
Měli bychom tedy ten pomalý šrot Python hodit z okna? Noo... ještě bych s tím počkal.
Není Python jako Python
Python totiž ještě neřekl poslední slovo :)
Referenční implementace Pythonu (CPython), kterou jsme použili v testu, totiž zdaleka není všechno, co můžeme ve světe Pythonu použít.
Velmi zajímavé je PyPy, které používá JIT kompiler a je téměr drop-in náhradou za CPython.
PyPy s Flaskem zvládne vrátit 60 požadavků za sekundu, tedy skoro trojnásobek toho co PHP a Slim.
A to se teprve zahříváme.
Další možností je části Python aplikace náročné na výpočet přepsat do Cčka a načíst je jako binární modul.
Proč ale přepisovat, když je tu Cython, který to udělá za nás?
Napíšeme tedy téměř běžný Python kód, kam pouze doplníme typové informace a označíme, co se bude volat z Pythonu.
Cython tento zdrojový kód převede do Cčka a zkompiluje do binárky, kterou můžeme importovat úplně stejným způsobem jako jakýkoliv běžný python modul.
A výsledek? Přes 400 požadavků za sekundu pro 30. číslo posloupnosti, tedy téměř 20x tolik co PHP.
Závěr
Zrychlení PHP ve verzi 7 se opravdu povedlo a pro celou řadu operací strčí referenční CPython do kapsy.
Svět Pythonu je ale velmi široký, a tak díky jeho mnoha projektům věnujícím se rychlosti (PyPy, Pyston, Nuitka, Cython)
dokáže v případě potřeby PHP dohnat a nakonec nechat daleko za sebou.
Zdrojové soubory benchmarku jsou dostupné na githubu.
Aktualizace 2.1.2021
Po 4 letech jsem zkusil benchmarky zaktualizovat a znovu spustit (ale už na novějším stroji). Jaký je výsledek?
PHP si oproti roku 2017 polepšilo 3-4x, čistý Python je stále pomalejší než PHP, ale už jen 4x (byl 5x).
Náskok Pypy a Cythonu se ale také trochu snížil. Cython byl rychlejší 18x než PHP, nyní už je "jen" 14x.
Nejsem si jist jak PHP (myslím že taky ne), ale Python nemá tail-recursion optimalizaci a ani se neplánuje. Tím trpí u těch vyšších hodnot. Pokud člověk píše v Pythonu a chce výkon, takovému kódu se vyhne. Takže by bylo zajímavější udělat test s něčím, co se pak skutečně používá. :-)