ugrás a tartalomhoz

PHP Tuning / hangolás / gyorsítás ötletgyűjtő topic

deejayy · 2011. Júl. 5. (K), 12.42
A topic lényege nagyjából annyi, hogy azokat az ötleteket vitassuk meg, amik kizárólag a PHP fejlesztő által elvégezhető optimalizációs tevékenységek. Tehát nem tartozik bele az apache konfig, speciális php modulok (pl. eacc), fájlrendszer (ezek hoszting esetén általában fixek, és az üzemeltető által is alkalmazhatóak), adatbáziskapcsolat és lekérdezések, stb.

Nem számít bele továbbá a szervertől a böngészőig tartó út, azaz milyen sávszélesség, hány fájlt tölt be, stb, ezek finomhangolására több irodalom és eszköz áll rendelkezésre.

Jöhetnek ide linkek, kódrészletek, két soros tippek is akár.

Egy trivialitást ellövök az elején:
- cache-elj, amit lehet (fájlrendszerbe, memcached-be)
 
1

Ilia.ws, PHP Core fejlesztő,

deejayy · 2011. Júl. 5. (K), 13.33
Ilia.ws, PHP Core fejlesztő, gyakran publikál jó dolgokat:
http://ilia.ws/files/Dutch_PHP_Conference_2010_OPM.pdf
2

Amit kiemelnék: - output

Hidvégi Gábor · 2011. Júl. 5. (K), 13.56
Amit kiemelnék:
- output buffering használata (ob_start())
- lekérdezések rendbetétele, egy jó index csodákra képes (EXPLAIN SELECT ...)
- a kód legyen egyszerű (magam részéről nem ajánlom semmilyen idegen keretrendszer használatát)
- notice-ok kiirtása (minden hibánál lefut a teljes php hibafeldolgozás, ami nagyban lassítja a kódot)

Amit hozzátennék:
- karakterláncoknál a szimpla idézőjelek használatával átlag tíz százalékkal gyorsulhat a feldolgozás a macskakörömhöz képest
4

output buffering?

Poetro · 2011. Júl. 5. (K), 14.16
Az output buffering mit gyorsít? Ugyanis a használatával a felhasználó később kapja meg az adatot, azaz lassabban fog megjelenni az oldalból bármi, ugyanis ha már hamarabb elkezdene a szerver kiírni a csatornára, akkor a felhasználó már el tudná kezdeni tölteni a tartalmat. Természetesen van olyan helyzet, ahol ez hasznos, de nem gondolnám, hogy a gyorsítást szolgálja.
6

Ez nekem is csak második

kuka · 2011. Júl. 5. (K), 14.29
Ez nekem is csak második olvasásra esett le, de Hidvégi Gábor a bufferinget az „Amit kiemelnék” csoportba sorolta, amely az „Amit hozzátennék” ellentétesének tűnik. Ebből úgy értem ő is a mellőzésüket tanácsolja.
8

Az "Amit kiemelnék"

Hidvégi Gábor · 2011. Júl. 5. (K), 15.41
Az "Amit kiemelnék" szekcióban a PDF-ben számomra fontos és tapasztalt sebességnövelő hatásokat említem, az "Amit hozzátennék"-ben pedig egy máshol olvasott és általam alkalmazott technikáról írtam.

Az Output Buffering témával kapcsolatban finomítanék: mi AJAX-os alkalmazást fejlesztünk, ahol az adatok feldolgozása ugye csak akkor történhet meg, amikor minden megérkezett a kliensre, és a válaszidőket látványosan felgyorsította a kisebb kiküldött adatmennyiség.
9

Grr. Akkor mégis

kuka · 2011. Júl. 5. (K), 15.49
Grr. Akkor mégis félreértettelek.

A bufferinget nem igazán értem hogyan gyorsíthat. Hacsak annyival nem, hogy a tartalom nem chunkedként megy ki, tehát időközben nem számol chunk méreteket, illetve ebből következően (jobban) tudja deflate-elni.
10

Elnézést kérek, mivel régen

Hidvégi Gábor · 2011. Júl. 5. (K), 16.45
Elnézést kérek, mivel régen csináltam, kiment a fejemből az ob_start egy fontos paramétere: ob_start('ob_gzhandler');

Megnéztem egy űrlapunkat, 408 kilobájt a nyers adat, 22k tömörítve, erre akartam célozni.
7

Hát, azt kell mondjam,

deejayy · 2011. Júl. 5. (K), 14.39
Hát, azt kell mondjam, leteszteltem.

Ha egy 100k-s stringet kiprintelsz ob nélkül, 100msec, vele 2msec.

De nekem nem az ob_start segített, hanem a php.ini-ben az output_buffering paraméter beállítása. Fogalmam sincs mi a különbség, de amíg csak php kódban volt az ob, addig döglassú volt, utána megtáltosodott. Jó tipp.
5

karakterláncoknál a szimpla

kuka · 2011. Júl. 5. (K), 14.24
karakterláncoknál a szimpla idézőjelek
Ezzel távoli rokon: echo paramétereit nem összefűzni, tehát echo 'összesen ' . $ossz . ' Ft'; helyett echo 'összesen ', $ossz, ' Ft'; .
11

szimpla || dupla idézőjelek

solkprog · 2011. Júl. 5. (K), 17.01
"gyorsulhat"-ot pontosítanám:
(egyszerű) karakterláncoknál gyakorlatilag nincs különbség.
Ha változott helyettesítünk be, vagy épp szerepel a karakterláncban a $ jel akkor van.
weblabor-os forrás igaz 2004-es a cikk, de talán szerintem még helytálló.
3

Ez egy elég jó optimalizációs

bb0072 · 2011. Júl. 5. (K), 14.13
Ez egy elég jó optimalizációs összefoglaló: http://developer.yahoo.com/performance/rules.html Többnyire frontendre vonatkozik, de a tartalomjegyzékben a server címkére kattintva listázza azt a 7 pontot, ami szerveroldali dolog. Ezekből is néhány apache beállítást érint, és van néhány, ami php, ráadásul ezek nem is feltétlenül triviális dolgok.
12

Tobbek kozott ezeket a

bh · 2011. Júl. 5. (K), 18.41
Tobbek kozott ezeket a szempontokat figyelembe veve implementaltak a Yslow-t, amely egy ugyes kis analizalo addon.
13

#teszt file_get_contents vs.

deejayy · 2011. Júl. 6. (Sze), 09.05
#teszt

file_get_contents vs. fopen-fread-fclose: 1 - 0

(ha a teljes fájlt be kell olvasni)
14

Átolvastam az Armando -

deejayy · 2011. Júl. 6. (Sze), 13.38
Átolvastam az Armando - Hawkins: Pro PHP Application Performance könyvet, tapasztalatok.

A könyvnek 70%-a szól arról, hogy mit tehetünk a PHP-n kívül, amivel gyorsíthatjuk a kiszolgálást (yslow, webszerverek, opcode cache, db, stb.)

15% szól arról, hogy hogyan mérjünk bottlenecket, ha van.

15% az, ami valóban a PHP optimalizálással foglalkozik, a lényeg:
- require_once helyett require
- echonál vesszővel fűzz össze, ne ponttal, és a változókat a stringen belül helyezd el ("helo $name")
- array-t foreach-csel járj végig
- nagy fájl beolvasni file_get_contents-szel gyorsabb, kicsit fopen/fread/fclose-zal (bár a kézi teszttel ezt megerősíteni nem tudtam, inkább cáfolni)
- osztályokban lévő változókat gyorsabb közvetlenül elérni ($class->var), mint getter függvénnyel ($class->getvar())

Ennél mondjuk többet vártam.
15

osztályokban lévő változókat

H.Z. v2 · 2011. Júl. 6. (Sze), 13.56
osztályokban lévő változókat gyorsabb közvetlenül elérni ($class->var), mint getter függvénnyel ($class->getvar())


Ezzel csak az a baj, hogy egyesek szerint a példányváltozók közvetlen elérése az objektum orientált programozással nem egyeztethető össze. (Java-soktól hallottam, nem tudom, mennyire igaz)
16

Dinamikus nyelvek

Poetro · 2011. Júl. 6. (Sze), 14.11
Lehet, hogy Java-ban igaz, de dinamikus típusokkal dolgozó nyelvekben, mint amilyen a JavaScript, PHP, jóval kevésbé. A rendszer elég lassú önmagában is, nem kell még szívatni is. A másik az, hogy egy példányt akár mikor tudok bővíteni új tulajdonságokkal, egyes nyelvekben pedig metódusokkal is. Ugyanez Java-ra nem igazán mondható el (bár nem megvalósíthatatlan).
18

Ehhez csak annyit (aztán

H.Z. v2 · 2011. Júl. 6. (Sze), 14.26
Ehhez csak annyit (aztán befejeztem az offolást), hogy Java kapcsán úgy került szóba, hogy egy fórumon kezdték összehasonlítgatni a C#-t, Scala-t, Java-t és előkerült, hogy a Javaban nem lehet a példányváltozókhoz getter/setter metódust definiálni úgy, hogy az egy értékadáskor lefusson, bezzeg a többiben! Na erre jött valaki(k)től a reakció, hogy az OOP-be nem is fér bele igazán az, hogy közvetlenül piszkáljuk az objektumok változóit (alias properties).
Szóval Javas mondta, de nem a Javaból kiindulva.

Ezt csak mint magyarázat, nem vitatkozni akarok...
17

foreach csak esszel

saxus · 2011. Júl. 6. (Sze), 14.18
- array-t foreach-csel járj végig


... de csak ha primitiv adattipusok vannak a tombodben, mert ha tombok, objektumok vannak benne, akkor latvanyosan gyorsabb tud lenni a for, foleg nagy adatmennyisegre. Persze, csak sorszamozott tomboknel. (kb. 2-3 eve mertem, talan PHP 4-l es 5.1-l, azota valtozhatott)
19

Az első hozzászólásban

Hidvégi Gábor · 2011. Júl. 6. (Sze), 15.04
Az első hozzászólásban említett PDF-ben írják, és én is csak megerősíteni tudom, hogy a PHP 5.3 gyorsabb az 5.2-nél, nálunk 10-20%-ot hozott. Új alacsony szintű adatbázishozzáférés-kezelő is van benne, a MySQL Native Driver, szerintem az is gyorsabb, mint a korábbiak.
20

#teszt Fájl írás esetén (bár

deejayy · 2011. Júl. 7. (Cs), 08.35
#teszt

Fájl írás esetén (bár nem fájlrendszer-tesztnek indult, de végül az lett), ha a cél fájlrendszer XFS, akkor akár 20-szor annyi ideig is tarthat egy már létező fájlt megnyitni írásra, mint egy nemlétezőt. Az okát nem nyomoztam ki, ext3-on a jelenség nem produkálható, máson nem próbáltam. (Ubuntu Linux 8.04 / kernel 2.6.24-16-server)

És ez bár már szerverhangolás téma, a php session adatokat semmiképpen nem érdemes XFS-re tenni.
22

Nos, kicsit tovább

deejayy · 2011. Júl. 7. (Cs), 10.29
Nos, kicsit tovább tesztelgetve ezt az XFS issue-t az derült ki, hogy a session kezelésre nincs hatással a dolog. Tehát az XFS-en tárolt session adatok módosítása esetén vagy letörli és létrehozza újra az adatfájlt, vagy más módon fér hozzá a fájlhoz (vagy beleszól a fájlrendszer cache).

Ha pedig memcached-re állítom a session kezelést, a script 1.3-1.8 ms-mal lassabban fut, mint a fájlrendszerbeli megoldás (függetlenül attól, hogy módosulnak-e a session adatok).
23

Maga a session_start()

deejayy · 2011. Júl. 7. (Cs), 10.53
Maga a session_start() függvény átlagosan 1 msec ideig tart.
21

Nemrég olvastam az "else

bh · 2011. Júl. 7. (Cs), 10.09
Nemrég olvastam az "else if"/"elseif"-ről is valahol, hogy nem ugyanúgy folyik az internal megvalósításuk. Fene gondolta volna, megnéztem és tényleg nem.

// else if
T_ELSE: 'else'
T_WHITESPACE: ' '
T_IF: 'if'

// elseif
T_ELSEIF: 'elseif'
"elseif"-re külön token van, így ha minimálisan is, de ez is gyorsíthat egy csöppet. Míg "else if"-nél az else ágba teszünk egy if-et.