Võrdlustestid
Phasis on väljakutsepõhistes JavaScript ülesannetes umbes kaks suurusjärku aeglasem kui V8. See ülempiir tuleneb otseselt PHP keskkonnas töötava interpretaatori kulust võrreldes natiivse JIT-kompilaatoriga. Mootori põimijale pole küsimus „kuidas see V8-ga võrdub?”, vaid „kas see on minu töö jaoks piisavalt kiire?”. Enamiku põimimistööde puhul on vastus jah.
Millal ülempiir tähtsust ei oma
- Mallide renderdamine – tavalise lehe SSR-laadne renderdus kestab tublisti alla 10 ms.
- Valideerimisreeglid – kasutaja antud JS-i vormi valideerimiseks käivituvad mikrosekunditega.
- Andmete teisendamine – sadade üksuste
array.map(transform)-i töötlemine võtab kümneid millisekundeid. - Liivakastis käitajad – lühikesed kasutaja skriptid, mille hostipoolne ajapiirang on 1 sekund, jätavad piisavalt jõudlusvaru.
Millal ülempiir on oluline
- Arvutusmahukad sisemised tsüklid – pilditöötlus, suurte massiivide koondamine, simulatsioonid. Teisalda arvutused natiivsesse PHP teeki ja ava see hostifunktsioonina.
- Reaalajas animatsioon – kõik, mis peab töötama sagedusel 60 kaadrit sekundis. See JS kuulub kliendipoolsesse rakendusse (brauserisse või natiivrakendusse), mitte põimitud mootorisse.
- Arvutusmahukate algoritmide JS ümberteostused – krüptograafia, pakkimine, parsimine. PHP-l on natiivsed vasted, mis on 1000× kiiremad; kasuta neid.
Sobiv mõttemudel: Phasis on PHP-laadsetesse rakendustesse põimitud JS-laadse loogika liimkiht. PHP host hoolitseb arvutuste eest; JS kiht seadistuse, harude ja väikeste teisenduste eest.
Mis teeb mootori tõhusamaks (võrreldes lihtsa puu läbiva käituriga)
- Baitkoodi VM – enamik sagedasi väljakutseid käib läbi
VM::executeopkoodilüliti, mitte AST. - Kohandatud väljakutsepinu – iga JS väljakutse hoiab oleku
VM::executesees ja salvestab kutsuja kaadri kogumisse; iga JS väljakutse jaoks ei looda uut PHP raami. Vt Baitkoodi VM § Kohandatud väljakutsepinu. - Inline-vahemälud – PC-põhine monomorfne vahemälu jätab prototüübiahela läbimise vahele, kui loetakse prototüübimeetodit eksemplarilt (
c.method()muster). - Kaadri hetktõmmise generaatorid – lihtsad generaatorikehad peatatakse, salvestades käituse oleku hunnikuobjekti, selle asemel et läbida PHP Fiberit.
- JsToPhp transpiiler – arvudest ja lokaalm muutujatest sõltuvad kehad (sh
obj.method(),new Ctor()jathis.memberlugemised) kompileeritakse PHP sulunditeks, mille PHP 8.5 jälgiv JIT-kompilaator teisendab natiivseks masinkoodiks. - JSON.stringify vahemälu –
JSON.stringify(o)salvestab tulemuse sisendobjekti külge koos transitiivse versiooni kehtetuks muutmisega, kiirendades süvakloonimise idioomiJSON.parse(JSON.stringify(o)).
Oma töökoormuse mõõtmine
php bench/run.php
See käivitab mikrojõudlustestide komplekti, mis sisaldub asukohas bench/microbench.js: mõned sünteetilised töökoormused (tsüklite aritmeetika, rekursiivsed funktsioonid, objektide loomine, prototüübimeetodite kutsumine, massiivi lisamine, JSON edasi-tagasi teisendus jne) ning väljastab iga testi mediaanse seinakellaaja. Kasulik mõistlikkuse kontrolliks; praegused tulemused salvestatakse iga CI jõudlustesti käigus asukohta BENCH.md.
Oma koodi mõõtmiseks asenda sinna mis tahes skript:
php -d xdebug.mode=off bench/run.php path/to/your-script.js
PHP-taseme profiilianalüüsiks töötab Xdebug profiilianalüsaator Phasis-iga täpselt nagu iga teise PHP rakendusega. Käivita skript xdebug.mode=profile all ja uuri cachegrind-väljundit, et näha, millised Phasis\ klassid võtavad enim aega.
Teekaart
Mis vähendaks V8 jõudlusvahet kõige rohkem, alustades hõlpsamini teostatavast:
- Polümorfsed inline-vahemälud — võimaldavad ühel
LOAD_MEMBERkutsekohal hoida 2-4 vahemällu salvestatud kuju, enne kui minnakse üle aeglasele väljakutsele. See aitab koodil, mis töötleb eri tüüpi vastuvõtjaid. yield*ja try-with-yield kaadripildi generaatori teel — nende kujude puhul suunatakse praegu Fiber-põhisesse puupõhisesse interpretaatorisse. Enne kui need on kaadripiltide jaoks ohutud, tuleb neid käsitleda selgesõnalise olekumasinaga (delegeeritud iteraatori edastamine, käitlejate pinu säilitamine peatamise ajal).- Asünkroonsed generaatorid ja
awaitkaadripiltidel — spetsifikatsioon ühendab generaatori peatamise mikrotööde järjekorraga. Kui baidikoodi keha toetab niiyieldkui kaawait, sobivad ka asünkroonsed generaatorid kaadripiltidega. - Parameetri tüübi tuletamine JsToPhpis — funktsiooni parameetrite vaiketüüp on numbriline, mistõttu
function (obj) { obj.method() }paneb kompilaatori loobuma. Parameetrite objektitüübi tuletamine nende kasutuse põhjal funktsiooni kehas võimaldaks kutsuda meetodeid funktsiooniargumentidel, ilma et vastuvõtja tuleks luua lokaalseltnewabil. - Otsene opcache-väljundi genereerimine — jätab JsToPhpi
eval()sammu vahele, kirjutades opcache-vormingus opkoodid otse. See on kõige keerukam punkt; ülejäänud saab teha olemasoleva arhitektuuri piires.
Ükski neist pole vajalik manustatud rakenduste jaoks, millele Phasis on mõeldud.