Přejít k navigační liště

Zdroják » PHP » PHP v rytmu Hip Hopu

PHP v rytmu Hip Hopu

Články PHP, Různé

Jazyk PHP je široce používaný, ale jeho výkon nepatří mezi jeho nejsilnější stránky. V rychlosti programovacích jazyků často dokonce zaujímá jedno z posledních míst. Vylepšit se to snaží nástroj z dílen Facebooku s názvem HipHop. Jedná se o převodník PHP skriptů do C++ a v článku si ukážeme, jak jej použít.

Vývojáři Facebooku se potýkali s výkonnostními problémy PHP, které používají pro generování frontendu Facebooku, a proto začali přepisovat kritické části aplikace do C++. Kód v C++ lze s PHP spojit skrz systém rozšíření, to se ale ukázalo jako problematické – jedna aplikace je tak psána zároveň ve dvou jazycích a ve dvou týmech, navíc jsou C++ programátoři dražší.

Řešením by tedy mohlo být přepsání části PHP, což by ovšem prý přineslo zrychlení jen o několik procent (zde je možné zapochybovat, protože například JavaScript v prohlížeči Google Chrome je několikrát rychlejší než PHP). Nakonec se tedy rozhodli vytvořit HipHop – převodník PHP skriptů do jazyka C++, který se po kompilaci vykonává mnohem rychleji. Podle slov jeho vývojářů snížil zátěž serverů o polovinu.

Princip funkce

Běžné zpracování PHP skriptů prochází přes několik vrstev. Nejprve se projde zdrojový kód, které se převede do jednotlivých jazykových elementů, tzv. tokenů. Z nich kompilátor vygeneruje bajtkód, tedy kód obsahující instrukce virtuálního stroje. Ten je zpracovává a převádí na instrukce procesoru, které se přímo vykonávají. Tento postup se nazývá interpretace a provádí se pro každý požadavek a každý vložený soubor.

Pro urychlení tohoto postupu se začaly používat PHP akcelerátory (například APC nebo eAccelerator), které v paměti uchovávají již zkompilovaný bajtkód, odpadá tedy načtení souboru, jeho parsování a kompilace.

HipHop tento postup kompletně obchází a používá vlastní. Zdrojový soubor zparsuje, provede optimalizace, určí datové typy, znovu zoptimalizuje a uloží jako zdrojový kód jazyka C++. Ten se poté zkompiluje pomocí běžného kompilátoru g++ (součást GCC), takže výsledný program obsahuje přímo nativní strojový kód pro cílový procesor. Tento postup se, na rozdíl od interpretace bajtkódu, provede pouze jednou, což výrazně zrychluje běh programu.

Omezení

Celé by to znělo příliš jednoduše, kdyby s kompilovaným přístupem nepřišla také některá omezení. HipHop podporuje pouze Unixové operační systémy (Linux, Mac OS X, BSD, …) a to pouze v 64bitové variantě. Navíc v současné verzi nedokáže fungovat s web serverem Apache; místo toho zkompilovaná aplikace přímo obsahuje HTTP server.

Další omezení jsou kladena přímo na PHP aplikaci, kterou chceme použít: oficiálně podporuje pouze vlastnosti z verze 5.2 (některé vlastnosti 5.3 již fungují, například anonymní funkce), většina PHP rozšíření není podporovaná, dokonce jsou podporovány pouze dvě databáze – MySQL a SQLite – a neexistují některé další funkce, obsažené přímo v PHP (třeba  function_exists).

Donedávna také nefungovaly „zlé“ funkce eval a create_function. Nyní už fungují, i když  kvůli nim musí HipHop obsahovat i interpret HPHPi. Takto vykonávaný kód ale nijak nevyužije výhod kompilace a je tedy mnohem pomalejší než zkompilovaná varianta.

Pozn.: Tyto funkce by se měly s obezřetností používat i při interpretování – nelze je uchovávat v cache bajtkódu a musí se tedy pokaždé parsovat znovu.

Naopak přímo obsažena jsou rozšíření, které pocházejí od Facebooku – XHProf a XHP.

Také je nutné mít na mysli, že jakákoliv změna kódu znamená překompilování celého projektu. Problematické jsou tedy například šablony v PHP kódu.

Instalace

HipHop se nedodává jako binární balíček a neoficiálně snad existuje pouze pro CentOS. Pro všechny ostatní systémy si musíte ručně zkompilovat aktuální git verzi (zatím neexistuje stabilní verze), což je na průměrném počítači „zábava“ na několik hodin. Pro kompilaci jsou vyžadovány asi dvě desítky závislostí. Nejjednodušší je kompilace na Ubuntu 10.10, protože autoři k ní dávají přímo návod a většina závislostí je dostupná ve výchozích repozitářích.

Výkon

Pozn.: Test byl prováděn na 64bitové distribuci Ubuntu 10.10 spuštěnou ve VirtualBoxu na MacBooku s 4 GB RAM, 2,2 GHz procesorem a 64bitového Mac OS X 10.6.

Nejdůležitější vlastností HipHopu je výkon výsledné aplikace. Pro porovnání jsem si vybral svou implementaci souborového žurnálu v Nette, který využívá struktury B+ stromu.

Kompilovaná verze tedy přinesla zrychlení přibližně o 40 %.

Takový žurnál ovšem není zrovna typické použití, mnohem důležitější je výkon reálných aplikací – například generování stránky s článek redakčního systému WordPress. Pro jeho kompilaci je ale potřeba použít mírně opravenou verzi.

Graf ukazuje, kolik server zvládl zobrazit stránek za sekundu, když se na něj zároveň posílalo 10 požadavků. Více než trojnásobné zrychlení přineslo použití cache bajtkódu, použití HipHopu dokonce více než osminásobné, resp. trojnásobné oproti verzi s cache.

Kompilace WordPressu trvala skoro hodinu a výsledná aplikace má 70 MB. Ta ovšem obsahuje už vše potřebné, včetně webového serveru, a lze ji jednoduše přenést na jiný server se stejným operačním systémem.

Chtěl jsem také otestovat HipHop na kompilaci Nette frameworku, to by si ale vyžádalo jeho částečné přepsání. Navíc tento framework cachuje šablony do PHP, což u kompilované verze nejde, ale šlo by pravděpodobně obejít pomocí funkce eval. – pozn.aut.

Závěr

Od HipHopu nelze očekávat, že se stane masově používaný. Má celkem specifické použití tam, kde současná infrastruktura už nestačí – po jeho aplikaci teoreticky stačí o polovinu méně výkonu pro vyřízení stejného množství požadavků. Žhavý kandidát na jeho nasazení je podle mne Wikipedie, která často trpí pomalostí generování stránek a systém MediaWiki, který ji pohání, je napsán právě v PHP.

Komentáře

Subscribe
Upozornit na
guest
52 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
belzebub

Nemuzu si pomoci, ale mam pocit ze vsechno co pochazi od facebooku je bastl, zprasenina a obecne neco co de proti vsemu co povazuji za „spravne“ v programovani..

Michal Kočárek

Budete-li trochu studovat, zjistíte, že kvalita kódu a rychlost provádění jsou v nepřímé úměře. (Tedy: čím „hezčí kód“, tím pomaleší provádění).

Jelikož HipHop vytvářel (ten hnusný, zlý, ošklivý a velký Big brother, pan) Facebook, je naprosto zřejmé, jaký má ten projekt účel – rychlost. A jelikož narazili na limity PHP, které nelze dál posunout, tak měli dvě možnosti – buď to všechno přepsat, nebo si napsat quick’n’dirty řešení – HipHop je druhou variantou, ale jak se zdá, funguje.

belzebub

Asi jsem se vyjadril moc neurcite – to co mi vadi je, ze misto rozumnych optimalizaci se provadi hromadny prevod do C++, ktery funguje pouze na specifickem OS a HW, ktery do sebe navic nabali vlastni web server – to je podle me ukazkova definice prasarny.
Jinymi slovy: „quick’n’dirty“ = prasarna.

Takze si vlastne rozumime.

Jinak za rozumnou optimalizaci, ktera neni PRASARNOU, povazuji v prvni rade nejaky profiling, nalezeni bottlenecku, pak bud pouziti lepsiho algoritmu, coz byva casto vice nez dostatecne – a pokud to nestaci, prepsani POUZE bottleneckove casti do neceho rychlejsiho.
A nebo koupeni vice pameti nebo dalsich pocitacu – coz vyzaduje znalost konkretni situace – nekdy to muze byt levnejsi, nekdy ne.

Michal

A vidíte to. Vy tu diskutujete v diskuzi a Facebooku to, zdá se, funguje tak jak potřebuje. Je mnohdy lepší udělat prasárnu, než si vymýšlet, jak by to asi bylo teoreticky možná někdy lepší.

JS

Proc by mel byt preklad do C++ prasarna? Pokud to chapu spravne, tak ten HipHop urcuje datove typy. Coz je ta hlavni optimalizace, jelikoz pokud vim, PHP je dynamicky typovany jazyk, takze musi typ zjistovat pri kazde operaci s promennou.

Nevim, jak byste vykonovou ztratu v tomhle chtel zjistit profilerem na urovni PHP. Samozrejme, muzete take profilovat samotne PHP; pak byste ale nejspis zjistil to, co vam rikam (staci se podivat, jak funguje hlavni interpretacni smycka), a predpokladam, ze to je to, co vyvojari HipHopu udelali.

keff

Jen připomenu, že hiphop nepsali vývojáři Facebooku pro vás, ale pro sebe – na vás je pak posoudit, zda řešíte podobná omezení s podobnými parametry a výsledky cost/benefit analýzy. Pokud ne, nikdo vás nenutí to používat.

Michal

Naprosto presne! :-)

Michal Kočárek

Ne, evidentně si nerozumíme.

Mohu pouze shrnout to, co psali i ostatní. Facebook to psal pro sebe, protože jemu to snížilo provozní náklady o 50%, jak tu psal autor článku.

Ukažte mi jiný způsob, jakým snížíte náklady o polovinu. Obávám se, že nákupem pamětí a procesorů a počítačů ty náklady nesnížíte. Optimalizace bottlenecků ty náklady taky neposune.

Ano, píšete-li kód v C nebo C++, není problém se ponořit v jedné proceduře do assembleru a část kódu přepsat. Ale v PHP to prostě nejde. Asi nerozumíte, že PHP má prostě nějaké limity, které už prostě dále posunout nejde bez změny technologií – a to přesně Facebook udělal.

A osobně si myslím, že je úplně jedno, je-li to řešení prasárna nebo ne. Důležité je, že to obsluhuje miliony požadavků za vteřinu, snížily se náklady, a ještě to funguje. Howgh.

Kit

Byla ještě jedna cesta s bottleneckem: Vytvořit si vlastní moduly PHP řešící právě tato místa třeba v C++ a ty potom v PHP používat. Když tuto techniku mohou používat vývojáři v Lua, tak proč ne v PHP?

Kit

Článek jsem četl. Jsou 2 možnosti:
– snažili se optimalizovat části, které nemá smysl optimalizovat ve stylu pravidla 90:10
– chtěli vykopnout z operační paměti interpretr PHP

Podle mne je pravděpodobnější to druhé. Při zpracování textů rozdíl mezi kompilovanými a interpretovanými jazyky IMHO není zas tak podstatný, paměťová náročnost však mohla hrát svou roli.

Michal Illich

Pokud vám bastl ušetří pár milionů dolarů, použijete ho?

alancox

Ona je otázka, zda nasazením HipHopu by se wikipedie naopak nezpomalila. Mám pocit, ale nehodlám to zkoumat, že wikipedia dost přepsala a značně zoptimalizovala zdrojové kódy řady funkcí v PHP ve své vlastní verzi.

Na rozdíl od HipHopu je zdokonalila použítím výrazně lepších algoritmů, než jsou v originálním PHP.

JAM3SoN

Aj napriek zlepšeniu algoritmov by ale stále bola réžia prekladu väčšia ako s použitím HipHop, či sa mýlim? HH by spracovával optimálnejší kód, čiže logicky by mal byť úmerne rýchlejší bez HH ale znova aj s HH.

Hrach

Wikipedie by IMHO ničeho nedosáhla, protože poměr generovaného obsahu ku tomu cachovanému v místích oblastech je zanedbatelný.

Tomáš

Ta optimalizace by se měla týkat kódu, ne vlastních dat. Takže jednou se to přeloží do něčeho rychlejšího a potom už to funguje se všemi daty.

mormegil

Nejde o optimalizaci dat, jde o to, že základem toho, že Wikipedie vůbec funguje, je masivní cachování. Tedy hodně velká část požadavků vůbec nedojde do PHP. (Ale když už tam dojde, tak by si to optimalizaci zasloužilo, byť si nejsem moc jist, jak moc je ten kód „PHP-bound“, i když prvotní testy HipHopu na MediaWiki vypadaly dost zajímavě.)

drevolution

Díky za hezké představení HipHopu. Neuvažujete, že napíšete i o dalších technologiích Facebooku?

David Majda

Nejprve se projde zdrojový kód, které se převede do jednotlivých jazykových elementů, tzv. tokenů. Z nich kompilátor vygeneruje bajtkód, tedy kód obsahující instrukce virtuálního stroje.

Popis je nepřesný. Z tokenů se musí ještě postavit abstraktní sytaktický strom (AST), aby byla jasná struktura programu. Teprve z něj se vůbec může generovat bajtkód.

v6ak

Popsaný problém s Nette není vhodné řešit evalem, mnohem lepší by IMHO byla AOT kompilace šablon. Možná by si to vyžádalo i nějakou úpravu šablonovacího systému. Ten eval by se hodil spíše do první ‚funguje to‘ verze.

Neříkám, že po tomto půjde již Nette bez problémů rozjet na Hiphopu, ale mělo by to řešit jeden z problémů.

JakubS

Pro první „funguje to“ verzi by snad mohlo stačit HipHopu předhodit projekt s již přeloženými šablonami (tzn. v tempu by byly PHP ekvivalenty Latte šablon).

Zkoušel to někdo?

v6ak

To může narozdíl od evalu skončit (podobně jako některé další věci) na dynamickém načítání skriptů, ačkoli jsou již předkompilované.

v6ak

PHP je v poněkud jiné situaci než V8: Na V8 obvykle buď běží jednoduchý skript (okořenění stránky), nebo nějaká webová aplikace (GMail), která se může malou chvíli načítat, ale pak má běžet rychle.

V prvním případě je režie malá, ve druhém př’ípadě není IMHO vzhledem k době běhu mnohdy až tak podstatná a kritická jako režie u PHP.

V8 má prostě JIT kompilátor (=> o néco vyšší režie při startu). A psát JIT pro PHP by se nevyplatilo, protože:
* u krátko běžících aplikací nemá dostatečný efekt a lepší je AOT (což vlastně udělali)
* AOT je jednodušší na implementaci než JIT.
* Změna životního cyklu PHP, která by umožnila nasadit efektivní JIT, by si mohla vyžádat přepsání aplikace a zasáhla by kvůli podpoře vláken dost i do vlastní implementace PHP.

Tedy, myslím, že udělali to nejjednodušší, co mohli, i když to tak možná na první pohled nevypadá.

TkTz

Vyborny clanek ! Jiz delsi dobu se rozhoduju hip hop vyzkouset z vlastni zvedavosti . Myslim si , ze je to projekt mirne vydareny a pro „svizny“ chod facebooku (pri tak velke zakladne uzivatelu) nezbytny. Tesim se na dalsi clanky open-sourceu z dilen facebooku :)

jxp

Ve druhém odstavci

což by ovšem prý přeneslo zrychlení

má se největší pravděpodobností být
což by ovšem prý přineslo zrychlení

Jinak pěkný článek, ale mám pocit, že kdyby najali tým programátorů, kteří by fb přepsali do RoR tak by to přineslo víc. On fb není složitá aplikace její síla je v tom, že jsou tam všichni :)

drevolution

Já tedy kód Facebooku neznám, ale rozhodně bych si nedovolil tvrdit, že Facebook není složitá aplikce :) Když člověk vezme v potaz množství dat, které jím proteče a to, že musí synchronizovat datacentra po celém světě, tak jsme rázem někde jinde.

Ano, kdybych napsal vlastní „Facebook“ a rozjel ho pro své kamarády, tak to pravděpodobně nebude moc složitá aplikace.

sidik

Jj, přepsání do RoR by přineslo víc. Třeba celkem solidní zpomalení a spoustu nepěkných chvilek při snaze to vůbec rozchodit :)

* Vlastní zkušenosti – doteď jsem vyzkoušel cca 12 různých RoR webových aplikací a jsou děsně pomalé. Navíc rozhejbat je bylo peklo. Ale na Redmine nedám dopustit :)

imploder

RoR – Ruby? To je další interpretovaný jazyk, podobně jako PHP. Pomohlo by přepsání do C++ nebo jiného kvalitního kompilovaného jazyka blízko hardwaru. I Java je mnohem rychlejší než PHP nebo Ruby.

sidik

Ano, Java… Ale možná tak co se vývoje týče. Pravda, nevím jak je a tom Java u webových aplikací ale cokoliv desktopového je otřesně pomalé. Protože ale Javu neznám, tak nejsem schopen říct, jestli je to Javou nebo jen neschopností programátorů, co jí používají.

pytel

Kdyz to neznate, tak proc mate potrebu se k tomu vyjadrovat?

registrovaný uživatel

To už je takový národní zvyk :-(*)

Kit

Díky za názor o RoR. Chtěl jsem ho vyzkoušet na vytvoření webové aplikace, ale nemám s ním žádné zkušenosti. Jen jsem si udělal pár konstrukcí v Ruby a došel jsem k závěru, že mi tento jazyk nevyhovuje. Pomalé aplikace rád nemám a tak zřejmě RoR ani nebudu zkoušet.

viroman

No zase abych napsal neco malo na obranu k RoR, tak v dobach kdy jsem weby delal (PHP) a take upravoval jiz vyse zmineny redmine (RoR), tak jsem si rikal ze rozhodne je to zajimavy jazyk a mozna by stalo za to pri vyvoji nejakych komplexnejsich systemu po nem sahnout. Co se rychlosti interpretace tyce nevim, redmine si rozhodne nejakou ramku vzit umel (tak mongrel je samotny psany v ruby pokud se nepletu a kod aplikace se tez naklada do ramky?? ale prosim opravte me pokud placam nesmysly) a celkove asi neni uplne nejlehci, ale zase kdyz clovek umi, myslim ze vyvoj muze byt nekde jinde (rychlost, zapouzdrenost,…) zejmena diky tem hook trikum atd…
Nicmene zmenil jsem praci, pouzivam perl (kdyz potrebuju jo vykon tak C) a je po ptakach;)

Jano

Cely problem rychlosti PHP je velka „vzdialenost“ od CPU. Optimalizacia PHP ma svoje hranice uz len tym ze bezi pod virtualnou masinou. Hip hop nerobi nic ine len „priblizuje“ kod blizsie k CPU. Cim sa ziska potrebny vykon.
Este jedna dolezita vec, ktora tu nebola spomenuta Apache + PHP nieje velmi optimalna kombinacia s pohladu uspory pamate. To sa da nahradit ciastocne kombinaciou nginx + php_cgi. Ked sa vsak pozriete na pamatove naroky hip hop kompilovanej aplikacie, zistite ze pamatove naroky tejto kombinacie su velmi nizke. Na jednom zeleze tak mozete prevadzkovat viac aplikacii, obsluzit viac uzivatelov. Ide teda aj o financnu usporu.

Viem si predstavit este lepsie riesenie ako hiphop a to je kompilacia priamo do ASM daneho CPU :-) Takto je nutna konverzia php -> g++, g++ -> asm.

cleb

Brrr, měli by to přejmenovat, jinak se toho netknu :)

jos

jedině METAL!

cleb

Ideálně, ale nemusí být. V podstatě by mi stačilo cokoli co není hip hop. Ať si to pojmenují třeba Justin Bieber, všechno bude lepší než hip hop.

Tschello

Takové problémy můžou mít snad jen na ČVUT :)

imploder

| +1

imploder

| -1

jos

takze Busta Rhymes by bylo OK?

cleb

Samozřejmě.

jos

tak asi tu ted budu za hlupaka, ze mezi rapem a hip-hopem nedelam rozdil (a nebo jeste za vetsiho hlupaka, protoze nevim jestli je Busta raper nebo hip-hoper)

no metal by stejne byl lepsi, to jo

shMoula

„JavaScript v prohlížeči Google Chrome je několikrát rychlejší než PHP“ nejak se u tohoto tvrzeni nechytam, jak si je mam vysvetlit?

Martin

Napište si složité funkce v JavaScript a PHP. Následně je spusťte na stejném počítači pomocí Chrome a php intrepretu a sledujte, za jak dlouho spočítají výsledek. Možná se míchají jabka s hruškama, ale danému tvrzení to bude odpovídat.

Asi jako věta
„JavaScript v prohlížeči Google Chrome je několikrát pomalejší než C“

shMoula

jo takhle, tak melo byt rovnou napsano interpretace, ted uz to chapu :-)

imploder

On totiž javascript v chrome není přímo interpretovaný, je kompilovaný do bajtkódu a až ten je (velmi rychle) interpretovaný.

kochi

Jak je na tom Hip Hop v porovnání s bCompiler – rozšíření PHP, které umožňuje uložit přímo onen Bytecode do souboru, načíst ho a následně rovnou interpretovat? Výhda? Funguje by byla, že by fungovalo jakékoli rozšíření.

Rozšíření funguje transparentně, že zvládá jak orig. zdrojové kódy, tak soubory uložené v bytecode.

http://www.php.net/manual/en/book.bcompiler.php

jos

HipHop je v produkčním nasazení, bCompliler je experimentální

http://www.php.net/manual/en/intro.bcompiler.php

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.