PHP optimizavimas

Kaip žinia, PHP nėra tikra programavimo kalba, t.y. PHP skriptai yra interpretuojami vykdymo metu, priešingai nei daugelis kompiliuojamų programavimo kalbų. Yra įvairių, pvz. kad ir kompanijos Zend siūlomų įrankių, kurie leidžia šiek tiek pagerinti šį reikalą, pvz. optimizuoti ir užkoduoti skriptus į bytecode, tačiau tai vistiek nėra taip greita kaip mašininis kodas.

Dėlko reikia gerinti PHP performancą? Pagrindinės priežastys, iš kurių išplaukia visos kitos:
- taupyti pinigus,
- laimingi klientai.

Be abejo, yra daug būdų kaip kuo daugiau išspausti iš turimų resursų.

Vienas iš jų - daugiau “hardware”. Galingesni serveriai, dual-procesoriai ir kt. ir pan. be abejo aiškiai leis pajusti pagerėjimą, jei tik dabartinė įranga su tuo nesusitvarko. Labai dideliems portalams, protingai sujungtos serverių sistemos leis ryškiai pagerint visą veikimą, na bet čia jau sistemų administratorių darbas. Hardwariškai galima pagerint ir specifines sritis, pvz. SSL užkodavimai su programine įranga atima daug jėgų iš procesoriaus, todėl galima įdiegti specialią plokštę, kuri tai atliks netrugdydama procesoriaus. Tokios kortos aišku kainuoja tūkstančiais, bet jei suksim nerealų internetinį biznį, tai negi neverta investuoti?

Na o dabar pats kodas. Visiškai aišku, kad jei programos kodas bus greičiau ir efektyviau vykdomas, galėsite daugiau nuveikti su ta pačia hardware įranga.

C bibliotekos - kaip žinia, PHP buvo sukurtas naudojant C kalbą. Nepaisant to, kad PHP vis greitėja, C programos veikia vistiek greičiau. Jei sukursite kažkokius sudėtingesnius algoritmus su C kalba ir jas vykdysite iš PHP - kodas veiks sparčiau. PHP tai galima atlikti sukuriant atskirus extension’us. Tokie PHP moduliai gali būti išoriniai, užkraunami skripto vykdymo metu, arba vidiniai - įkompiliuojami tiesiai į PHP vidurius. Aišku, naudodami savo extensionus prarasite dalį to paprastumo, patogumo ir portabilumo, kurį suteikia PHP, tačiau specifiniais atvejais tai suteikia tik privalumus.

Kodo pagreitinimas. PHP yra interpretuojama programavimo kalba. Tai reiškia, kad kaskart vykdant PHP skriptą, Zend variklis jį nuskaitys, išparsins, įkompiliuos į atmintį ir tada įvykdys. Kadangi PHP skriptai paprastai nesikeičia bent jau nuo vienos užklausos iki kitos, parsinimas ir kompiliavimas kartojami kaskart ir yra laiko ir resursų švaistymas. Kodo greitinimo produktai šiandien leidžia to atsisakyti palaikant sukompiliuotus skriptus atmintyje. Zend kompanija šiam reikalui turi paruošusi rimtų produktų, kurie kainuoja ir nemažus pinigus, tačiau egzistuoja ir nemokami kodo acceleratoriai.

Turinio kešavimas. Įsivaizduokime, kad draugas paskambina Jums ir paprašo sužinoti kokia šios dienos “Vakaro žinių” antraštė. Jūs nueinate iki artimiausio spaudos kiosko, grįžtate namo ir pranešate draugui apie antraštę. Jums paskambina antras draugas ir paprašo to paties. Ar vėl eisite iki kiosko? Na, turbūt nebent tokiu atveju, jei pirmo apsilankymo metu įsimylėjote kioskininkę. Jei taip nėra, Jūs pakankamai protingas, kad suprastumėt jog pateikta užklausa yra analogiška, ir tikėtina, kad atsiminsite antraštę. Deja, HTTP serveris nėra toks protingas, ir turbūt labai dažnai laksto į spaudos kioską (tarkim, duomenų bazės serverį). Turinio kešavimo idėja paprasta: serveris dirba sunkiai kad sugeneruotų rezultatą į užklausą. Šiuos duomenis jis tada laiko po ranka, ir kai gauna tokią pačią užklausą, tiesiog panaudoja prieš tai sugeneruotus duomenis. Tai be abejo ir sumažina web serverio apkrovimą, tačiau efektas daug aiškiau matysis duomenų bazės serveryje, kuris gaus labai mažai užklausų. Viskas atrodo paprasta, tačiau smulkmenose iškyla ir problemų. Pavyzdžiui, kaip atpažinti ar užklausa yra panaši užklausa, ar skiriasi (ar mano draugas prašo šios dienos “Vakaro žinių” antraštės, o gal vakarykštės, o gal nori “Ekstra žinių” arba jis gyvena Anglijoj ir skaito Didžiosios Britanijos “Vakaro žinias”). Taip pat reikia nuspręsti, kaip valdyti kešavimą, kada ištrinti senus duomenis ir kaip tinkamai valdyti resursus (pvz. negaliu atsiminti visų laikraščių antraščių, tai kurią yra geriausia pamiršti).

Failų lygio kešavimas. Jei puslapis yra matomas daugeliui vartotojų toks pats, galima užkešuoti jį visą į vieną failą. Įsivaizduokime, tarkim delfi.lt titulinį puslapį. Nauji straipsniai tarkim įrašomi kas 15 minučių. Galime vykdyti kešuotų duomenų laikymą tarkim 5 minučių intervalu. Dabar, jei tarkim į puslapį per 5 minutes ateis 1000 lankytojų, tik vienas PHP skriptas ir vienas kreipimasis į duomenų bazę bus įvykdytas vietoj 1000. Neskaitant šito vieno laimingojo, likusiems duomenys bus patiekiami tiesiog iš kešo, tarsi tai būtų statiniai HTML failai. Turint laiko limitą šiems kešuotiems failams, nauja antraštė blogiausiu atveju atsiras po 4min 59sek. Be to, galima ir šitą nepatogumą lengvai apeiti, atsiradus tarkim labai svarbiam straipsniui apie Brazausko atsistadynimą, kurį būtina paviešinti akimirksniu. Pavyzdžiui, turint kokį nors patogų skriptą, kuris vieno mygtuko paspaudimu “rankiniu būdu” panaikina kešuotus rezultatus ar ir pats juos sugeneruoja iš naujo. Kartais tenka apsvarstyti ir įvairių užklausų variacijas, neskaitant unikalaus URL adreso. Skirstant kešuotus duomenis verta apsvarstyti ir GET parametrų, globalių http kintamųjų, sausainukų (”cookies”) įtraukimą į kešavimo sūkurį. Pavyzdžiui, reikia užkešuoti skirtingus titulinius puslapius, priklausomai nuo vartotojo geografinės vietos ir pan.

Dalinis kešavimas. Failų kešavimo privalumai aiškus, tačiau dažnai tam tikri puslapio laukai yra priklausomi nuo unikalaus vartotojo. Pavadinkim tai “welcome, UserName” problema. Šiuo atveju visas puslapis yra vienodas visiems vartotojams, tačiau mes įterpiame asmeninę žinutę puslapio viršuje. Nebegalime kešuoti viso puslapio, nebent mums nesvarbu, kad Petras, Jonas ir Juozas matys užrašą “welcome, Marytė”, tai yra pirmojo asmens, kuris davė užklausą pirmasis, vardą. Sprendimas yra dalinis puslapių kešavimas. Mes visdar galime kešuoti didžiąją dalį puslapio, kuri, tikėtina ir naudoja didžiąją dalį užklausų į duomenų bazės serverį. Tai nusprendžiama jau API lygyje, tai yra PHP skripte, kuriam nurodytas specialus segmentas, kuris turi būti pakeistas perduotu parametru ar priklauso nuo skripto pobūdžio.

Duomenų bazės tarpinis kešavimas. Šis būdas leidžia atskirti PHP kodą nuo duomenų bazės. Vietoj to, turime skriptą, kuris vykdomas periodiškai ir ištraukęs duomenis iš duomenų bazės serverio, išsaugo juos į HTML gabalus failuose, kurie po to įterpiami kai skriptas formuoja rezultatus. Sprendimas šiek tiek sudėtingas ar ne itin patogus, tačiau kai kuriais atvejais gali būti naudingas.

Duomenų bazės optimizavimas. Programuotojai nesivadintų programuotojais, jei didžiausio dėmesio neskirtų būtent kodo optimizavimui. Deja, net greičiausiai veikiantis algoritmas neatstos laiko, kurį sugaiš prastai parašyta SQL užklausa į duomenų bazės serverį, kurios netinkamai suformuotos ar nenaudoja reikalingų indeksų. Jei skiriate laiko savo kodo gerinimui, skirkite jo ir išsiaiškinti, kaip išgauti geriausia, ką gali duoti duomenų bazės serveris. Kaip ir duomenų kešavimo atveju, nedidelės pastangos duos labai gerų rezultatų, kai paoptimizuosite sąveiką su duomenų baze.

Gzip kompresija. Kartais optimizavimas nebūtinai reiškia kodo taisymą ar duomenų nuskaitymą iš serverio ar failų. Optimizuoti galime ir duomenų perdavimo galiniam vartotojui sąskaita. Didelių duomenų perdavimas taip pat kaip ir viso serverio pralaidumo išnaudojimas gali nepatikti vartotojui. Nors čia atrodo jau negalime daug ką pakeisti, tačiau duomenų suspaudimas čia gali pagelbėti. Didžioji dalis šiuolaikinių naršyklių gali gauti suspaustus duomenis ir sugeba pačios juos automatiškai išarchyvuoti. Naudoti duomenų spaudimą paprasta: tereikia įjungti “zlib.output_compression = on” php.ini nustatymuose. Reikia pažymėti, kad duomenų suspaudimas suteikia darbo procesoriui kiekvienos užklausos metu. Tai vėlgi galime apeiti, apjungę kompresiją su kešavimu. Tiesiog kešuojame jau suspaustus duomenis.

Kompiuterių tinklo struktūros gerinimas, nors ir nėra programuotojo reikalas, tačiau taip pat galimas puslapio veikimo gerinimo būdas. Kai kurie kompiuterių tinklų įrenginiai gali atlikti jau paminėtus optimizavimo metodus hardware lygmenyje ir turi daugybę kitų galimybių.

Ką pasirinkti? Be abejo, kiekvieno atvejis yra unikalus, todėl reikia atkreipti dėmesį, kokių iškyla problemų būtent Jūsų puslapiuose. Taipogi, atsirinkite, kokia įranga ar kokie metodai yra Jums prieinami, ir ką jais galite pasiekti. Kai atsakysite į šiuos klausimus, optimizuoti bus lengviau.

Optimizavimą palengvina ir vis gelbsti mūsų naudojama programinė įranga. Vis naujesnė išleidžiama web serverio ar PHP versija reiškia, kad ji turi kažkokių pataisymų, susijusių ir su optimizacija, todėl visada verta įsidiegti stable naujausias versijas. PHP 5 versija su Zend varikliuko antra versija siūlo naujas objektinio programavimo galimybes, kurios ne tik palengvina patį programavimą, bet ir pagreitina skriptų veikimą. Duomenų bazių serveriai tai pat tobulėja - MySQL 5 versija turi daugybę galimybių, kurių iki šiol nebuvo.

Optimizavimas būtinas ne tik PHP ir ne tik dėl pinigų taupymo ir vartotojų patenkinimo. Pajutę optimizavimo svarbą tapsite geresniu programuotoju, taip pat ir pagerinsite PHP įvaizdį web technologijų kovoje.

5 Responses to “PHP optimizavimas”

  1. enc Says:

    Zend’as turi savo Zend Encoder ne dėl to, kad sukompiliuoti skriptai veiktų greičiau, bet dėl to, kad svetimos akys nepamatytų išeities kodo (source code). Šitas dalykas kainuoja tikrai brangiai, tačiau Zend Optimizer, kuris yra skirtas optimizacijai (skaitykit pavadinima, d’uh) tikrai pagreitina skripto vykdyma nuo kelių iki keliasdešimties kartų.

    Dėl failų kešavimo, tai aš asmeniškai viską palieku squid’ui ..) be to tinkamai sukonfiguruotas apache mod_cache ir kiti kešavimo moduliai duoda tikrai neblogų rezultatų.

    Duombazėse prasideda tikras linksmumas ..) dideliuose projektuose/portaluose su n-esdešimt lentelių queriai pradeda darytis ilgi. Ir trumpiausias užima selekta bent iš dviejų ar trijų lentelių. Svarbiausiai, kad viskas atitiktų normines formas (bent jau 3′iąją), tada tik netingėk select’ų rašyti ,.)

    php.lt kažkur mėtėsi benchmark’ai dėl skirtingų ciklų ir pan. Iš ten man įstringo vienintelė detalė: for(){} ciklas vykdomas iki 6 kartų greičiau, jeigu prieš ciklą yra apsibrėžiamas mėsinėjamo masyvo dydis ..)

    Tokie mano du centai ,.)

  2. medutis Says:

    Na nepaminėjau Zend encoder, bet Zend’as turi prikūręs daug ir kitų įrankių, tarp jų ir Zend Optimizer. O šiaip jau yra atsiradę saitų, kurie siūlo atkoduoti Zend encoder’io užkoduotus skriptus :)
    Squidas aišku jau yra adminų reikalas, dažniausiai. Gerai kai esi universalas. Bet straipsnis sakyčiau gan skubotai kurtas/verstas, ir ganėtinai viskas abstrakčiai išdėstyta

  3. mid Says:

    norminių formų atitikimas dar nereiškia gero performanco! geras performancas yra tas mažas lašelis tarp teorijos ir praktikos :)

  4. enc Says:

    mid: ar esi dirbęs su tokiu projektų kur praktika palaužė teoriją? ..) man vieną kartą teko dirbti, bet ten buvo kalta biurokratija ,.)

  5. expert Says:

    Kartais optimizuojant puslapį duombazėje tenka atsisakyti norminių formų ir dubliuoti duomenis. Tarkim SAP’o duombazės atrodo žiauriai. Ten pilna duomenų dubliavimo, ir būtent tam, kad queris būtų daromas vienoje lentelėje, o ne per tris.
    Gerai padeda kešuojami viewai, kur view tik ne visi turi tokį malonumą juos naudoti.

Leave a Reply