PHP: Mīti un patiesības par ātrdarbību. II daļa
Iepriekšējā rakstā apkopoju, manā skatījumā, visklasiskākos mītus un patiesības par PHP funkciju un valodas konstrukciju ātrdarbību, kurus līdz šim esmu dzirdējis vai redzējis. Šinī rakstā būs vairāki piemēri ar konstrukcijām, kur ātrdarbība (lēndarbība) ne vienmēr ir acīmredzama. Piemēram, zinājāt, ka funkcijā lokālā mainīgā inkrementēšana būs ~2x ātrāka nekā globālā?
Iepriekšējā rakstā apkopoju, manā skatījumā, visklasiskākos mītus un patiesības par PHP funkciju un valodas konstrukciju ātrdarbību, kurus līdz šim esmu dzirdējis vai redzējis. Šinī rakstā būs vairāki piemēri ar konstrukcijām, kur ātrdarbība (lēndarbība) ne vienmēr ir acīmredzama. Piemēram, zinājāt, ka funkcijā lokālā mainīgā inkrementēšana būs ~2x ātrāka nekā globālā?
$var = ‘tests’ būs ātrāks par $var = „tests”, jo php meklēs mainīgos iekš „...”, savukārt iekš ‘...’ nē. Kaut gan pēdējās versijās šī atšķirība vairs nav tik izteikta;
a) echo „viens”, „divi”, „trīs” būs ātrāks par echo „viens” . „divi” . „trīs”. T.i. rindas savienošana būs lēnāka, nekā to fragmentu izvadīšana.
b) ($x=0; $x < count($array); $x) funkcija count tiks izsaukta katrā cikla solī. Piemēram var lietot šādi -
for ($j = 0, $max = count($array); $j < $max; $j++);
c) PCRE regex būs ātrāks nekā EREG;
d) $str = 'This is a string';
if (isset($str[1])) būs ātrāks nekā if (strlen($str)>1))
e) Lokālā mainīgā inkrementēšana (funkcijās) būs ~2 reizes ātrāka nekā globālā;
f) $this->prop++ būs ~3 reizes lēnāka nekā lokālā mainīgā (t.i. $prop++);
g) Nedefinētā mainīgā inkrementēšana būs ~8 reizes lēnāka nekā predefinētā;
h) $obj =& new SomeClass() bus ātrāks nekā $obj = new SomeClass(), savukārt $obj =& $someClass->f() būs 2 reizes lēnāks nekā $obj = $someClass->f();
i) while(list($key) = each($aHash)) $aHash[$key] .= "a" būs ātrāks nekā foreach($aHash as $key=>$val) $aHash[$key] .= "a";
j) is_array() definētai vērtībai būs 2..3 reizes ātrāks nekā is_array() nedefinētai vertībai. Līdz ar ko pareizāk būtu lietot - if (isSet($foo) AND is_array($foo));
k) neitīvo konstrukciju lietošana būs ātrāka:
// būs ātrāks
$data = file_get_contents("some_file");
// nekā:
$data = '';
$fp = fopen("some_file", "r");
while ($fp && !feof($fp)) {
$data .= fread($fp, 1024);
} fclose($fp);
Vairāk var lasīt arī šeit:
http://www.hm2k.com/posts/50-php-optimisation-tips-revisited
Nobeigumā vēlējos vēlreiz atgādināt, ka šos piemērus nevajadzētu uztvert kā baltu patiesību. Vēl jo vairāk, ka to vai citu funkciju un konstrukciju ātrdarbība var atšķirties no PHP versijas, testa vides un testēšanas veida. Šeit apskatītie piemēri pārsvarā „sasēņoti” interneta tīmeklī un tikai tie, kuriem atradu apstiprinājumu vairāk par vienu vietni vai forumu.
Der atcerēties, ka ātrdarbība un universālums (arī koda pārskatāmība) dažkārt ir apgriezti proporcionāli lielumi. Jāizsver arī alternatīvās konstrukcijas pielietojums konkrētā uzdevuma veikšanā.
To, ka for ciklā var nodefinēt divus mainīgos reāli neiedomātos! (stupid)
Ja tu sāc uztraukties par šādu sīkumu ātrdarbību, tad apsveicu. Būtībā problēmas parasti ir stipri citās vietās - db noslodzes, pieprasījumi ārējiem resursiem, kļūdaina loģika, utt.
imho h) jau vairs nav aktuāli kopš php5 versijas.
Atbilstošo konstrukciju izmantošana atbilstošām darbībām arī ir viens no programmas loģikas stūrakmeņiem :)
Svarīgi arī kur, ko un cik lielā mērā ļauts ietekmēt...
Šeit jau vairāk dzīšanās pēc milisekundēm. Vēl ir arī atmiņas noslodze!
Dzīšanās pēc milisekundēm šeit ir pilnīgi nevietā manuprāt, jo ir procesi, kuri aizņem strašna vairāk laika un resursa - piemēram grābstīšanās gar cietni, datu apstrāde, meklēšana pa tabulām, utt. un tur ir developeriem izstrādātas daudz visādas aplikācijas, kuras palīdz samazināt izpildes laikus aš pat 20x nepārspīlējot.
Milisekundes varbūt arī nedos plānoto gandarījumu :), bet komentārs par atmiņas noslodzi ir vietā. Jo, lai arī cik serverim atmiņas būtu, PHP.ini ir savi limiti...
Tas, laikam, būtu atsevišķa stāsta vērts :D
ar php.ini tur maz sakara - ir pāris 100mb tabulas dzenātas šurpu turpu uz defaultajiem parametriem un nekādas vainas. varbūt kādu reizi nesanāk kaut kāda darbība dēļ php.ini ierobežojumiem, bet to var ātri apiet sadalot apstrādājamo datu apjomu. vispār front-end aplikācijām jābūt ne tik strašna rijīgām, lai tur ņemtos ar konfigu pielāgošanu. protams nerunāju par projektiem ar pastāvīgu noslodzi >300 hitu sekundē. drīzāk paskaties eaccelerator, memcache un citu serverside risinājumu virzienā. pareizi lietoti tie var dot neiedomājamu pieaugumu performancē (piemēram kešojot 5 tabulu advancētu joinu).