PHP futástesztek, avagy a PHP benchmark

PHP futástesztek, avagy a PHP benchmark

PHP futástesztek, avagy a PHP benchmark

PHP-ban írt forráskódjaink futási idejét sokban befolyásolja a szerver sebessége, a php verzószáma és a megírt kódban felhasznált függvények fehasználási módja. Az összehasonlításban mért időegységek más-más tesztkörnyezetben eltérhetnek, de az arányok ábrázolására tökéletes és helytálló. A könnyebb megértés érdekében csak a legegyszerűbb függvényeket és eljárásokat fogom bemutatni. Saját futásteszt elvégzéséhez javaslom a Online PHP Functions és PHP Benchmark Script benchmark szkriptjeit. (A mért eredmények meglepőek lehetnek.)

A teszteket a phpbench.com eredményei alapján végeztük el. A weboldalon megtalálhatóak a méréshez felhasznált PHP forráskódok is.

MEGJEGYZÉS:

Tartsd észben, hogy sok frissítés is szükséges lehet, hogy a újra és újra igazolást nyerjenek a teszteredmények.
Egyes frissítések után a számok drasztikusan változhatnak.
Feltételezem, ez annak köszönhető, hogy a PHP "garbage collector" tetszőleges időközönként fut le. Emellett a szerveren futó más folyamatok is befolyásolják a futásidőt.

Változó típusának ellenőrzéseisSet() vs. empty() vs. is_array()

Az isSet() és empty() metódustok teljesítménye. 2000 futtatás alapján

+ 109 %

isSet() deklarált változó esetén

Teljes futtatási idő: 48 ms

+ 104 %

empty() deklarált változó esetén

Teljes futtatási idő: 46 ms

+ 104 %

isSet() nem deklarált változó esetén

Teljes futtatási idő: 46 ms

+ 102 %

empty() nem deklarált változó esetén

Teljes futtatási idő: 45 ms

+ 104 %

isSet() deklarált, tömb típusú változó esetén

Teljes futtatási idő: 46 ms

+ 114 %

empty() deklarált, tömb típusú változó esetén

Teljes futtatási idő: 50 ms

+ 100 %

isSet() nem deklarált, tömb típusú változó esetén

Teljes futtatási idő: 44 ms

+ 100 %

empty() nem deklarált, tömb típusú változó esetén

Teljes futtatási idő: 44 ms

+ 392 %

is_array() tömb esetén

Teljes futtatási idő: 173 ms

+ 388 %

is_array() string esetén

Teljes futtatási idő: 171 ms

+ 1288 %

is_array() nem deklarált változó esetén

Teljes futtatási idő: 568 ms

+ 1433 %

isSet() AND is_array() nem deklarált változó esetén

Teljes futtatási idő: 632 ms

Következtetés:

Az isSet() és empty() azonos teljesítménnyel futnak. Mindig ellenőrizd, hogy a változó létezik-e, mielőtt a típusát vizsgálod.
Pl.: if (isSet($foo) AND is_array($foo))

Az & referencia szerinti átadás operátor használata...ún. "alias"

Jó technika az alias operátor használata multidimenzionális tömbök esetén? 1000 futtatás alapján

Pl.: $person = &$aHach["country"]["zip"]["street"]["number"]["name"]

+ 204 %

$alias = $aSingleDimArray[$i]

Teljes futtatási idő: 261 ms

+ 100 %

$alias = &$aSingleDimArray[$i]

Teljes futtatási idő: 128 ms

+ 207 %

$alias = $aMultiDimArray[$i]["aaaaa"]["aaaaaaaaaa"]

Teljes futtatási idő: 265 ms

+ 353 %

$alias = &$aMultiDimArray[$i]["aaaaa"]["aaaaaaaaaa"]

Teljes futtatási idő: 451 ms

+ 227 %

$alias = veryMultiDimArray[$i]["a"]["aa"]["aaa"]["aaaa"]["aaaaa"]

Teljes futtatási idő: 290 ms

+ 580 %

$alias = &$veryMultiDimArray[$i]["a"]["aa"]["aaa"]["aaaa"]["aaaaa"]

Teljes futtatási idő: 741 ms

Következtetés:

Egydimenziós tömbök esetén az alias használata kedvező eredménnyel jár, azonban többdimenziós tömbök esetén teljesítményvesztéssel jár.

A =& cím szerinti átadás operátor használata$obj = new SomeClass() vs. $obj =& new SomeClass()

Célszerű a cím szerinti átadás operátor használata új objektum péládnyosításakor? 1000 futtatás alapján

+ 100 %

$obj = new SomeClass();

Teljes futtatási idő: 115 ms

+ 132 %

$obj =& new SomeClass();

Teljes futtatási idő: 152 ms

Következtetés:

Nincs jelentős teljesítménybeli különbség.

Vezérlési szerkezetekswitch/case/default vs. if/elseif/else

Van különbség a switch és if vezérlési szerkezetek teljesítménye között? 1000 futtatás alapján

+ 118 %

if and elseif (== használatával)

Teljes futtatási idő: 60 ms

+ 117 %

if, elseif and else (== használatával)

Teljes futtatási idő: 60 ms

+ 100 %

if and elseif (=== használatával)

Teljes futtatási idő: 51 ms

+ 129 %

if, elseif and else (=== használatával)

Teljes futtatási idő: 66 ms

+ 121 %

switch / case

Teljes futtatási idő: 62 ms

+ 121 %

switch / case / default

Teljes futtatási idő: 62 ms

Következtetés:

A switch/case és if/elseif használatában nincs jelentős teljesítmény különbség. Figyeljük meg, hogy az === (érték és típus szerinti azonosság) minimálisan gyorsabb, mint az == (érték szerinti hasonlítás)

Idézőjelek használatadupla (") vs. egyszeres (') idézőjel

Van különbsége a dupla és az egyszeres idézőjel használata között? 1000 futtatás alapján

+ 128 %

egyszeres (') idézőjel. Üres string esetén: $tmp[] = '';

Teljes futtatási idő: 82 ms

+ 109 %

dupla (") idézőjel. Üres string esetén: $tmp[] = "";

Teljes futtatási idő: 70 ms

+ 128 %

egyszeres (') idézőjel. 20 byte-os szöveg esetén : $tmp[] = 'aaaaaaaaaaaaaaaaaaaa';

Teljes futtatási idő: 82 ms

+ 149 %

dupla (") idézőjel. 20 byte-os szöveg esetén : $tmp[] = "aaaaaaaaaaaaaaaaaaaa";

Teljes futtatási idő: 95 ms

+ 105 %

egyszeres (') idézőjel. 20 byte-os szöveg és 3 $ jel esetén : $tmp[] = 'aa $ aaaa $ aaaa $ a';

Teljes futtatási idő: 67 ms

+ 122 %

dupla (") idézőjel. 20 byte-os szöveg és 3 $ jel esetén: $tmp[] = "aa $ aaaa $ aaaa $ a";

Teljes futtatási idő: 78 ms

+ 100 %

dupla (") idézőjel. 20 byte-os szöveg és 3 \$ jel esetén: $tmp[] = "aa \$ aaaa \$ aaaa \$ a";

Teljes futtatási idő: 64 ms

Következtetés:

Úgy látszik, a jelenlegi PHP verziókban nincs jelentős különbség.

Ciklus számlálókFor vs. While

Van különbség a for és while ciklus számlálók léptetése között?

+ 102 %

for($i = 0; $i < 1000000; ++$i);

Teljes futtatási idő: 16388 ms

+ 100 %

$i = 0; while($i < 1000000) ++$i;

Teljes futtatási idő: 16129 ms

Következtetés:

Az esetek 90%-ában a while ciklus számlálása valóban kissé gyorsabb.

Ciklus számlálókFor-loop test

Megéri a ciklusok számát előre kalkulálni?

Pl.: "for ($i=0; $i<sizeOf($x); $i++)" helyett "for ($i=0; $i<$size; $i++)"

1 cilkus alapján, mely 1000 iterációból áll.

+ 100 %

Előkalkulációval - count()

Teljes futtatási idő: 47 ms

+ 63594 %

Előkalkuláció nélkül - count()

Teljes futtatási idő: 29869 ms

+ 115 %

Előkalkulációval - sizeof()

Teljes futtatási idő: 54 ms

+ 62725 %

Előkalkuláció nélkül - sizeof()

Teljes futtatási idő: 29461 ms

Következtetés:

Az eredmény nem meglepő. Ezt a legegyszerűbb implementálni bármely alkalmazásban. Az eredmények önmagukért beszélnek. Ebben a kérdésben a legszélesebb az egyetértés az online PHP közöségek körében.

Módosító ciklusok: foreach() vs. for vs. while(list() = each())

Mi történik, ha a tömb bejárását módosítjuk, minden lépésnél felülírva az adott elem értékét?

A Hash tömbünk 100 elemből áll, melynek kulcsak 24 byte-osak, értékei 10k adatot tartalmaznak.

+ 632 %

foreach($aHash as $key=>$val) $aHash[$key] .= "a";

Teljes futtatási idő: 107 ms

+ 213 %

while(list($key) = each($aHash)) $aHash[$key] .= "a";

Teljes futtatási idő: 36 ms

+ 100 %

$key = array_keys($aHash);
$size = sizeOf($key);
for ($i=0; $i<$size; $i++) $aHash[$key[$i]] .= "a";

Teljes futtatási idő: 17 ms

Következtetés:

Ez a példa jól mutatja, hogy egy foreach ciklus mennyire drasztikus teljesítményromlást képes magával hozni.

String kiíratásecho vs. print

Van különbség a két kiírató függvény teljesítménye között? 1000 Output Bufferelés alapján.

+ 100 %

echo ''

Teljes futtatási idő: 23 ms

+ 101 %

print ''

Teljes futtatási idő: 23 ms

+ 293 %

echo 'aaaaaaaaaaaaaaaaaaaaaaaaaaaa'

Teljes futtatási idő: 67 ms

+ 283 %

print 'aaaaaaaaaaaaaaaaaaaaaaaaaaaa'

Teljes futtatási idő: 65 ms

+ 279 %

echo 'aaaaaaa'.'aaaaaaa'.'aaaaaaa'.'aaaaaaa'

Teljes futtatási idő: 64 ms

+ 288 %

echo 'aaaaaaa','aaaaaaa','aaaaaaa','aaaaaaa'

Teljes futtatási idő: 66 ms

+ 284 %

print 'aaaaaaa'.'aaaaaaa'.'aaaaaaa'.'aaaaaaa'

Teljes futtatási idő: 65 ms

+ 677 %

$a = 'aaaaaaa';
echo 'aaaaaaa'.$a.'aaaaaaa'.$a

Teljes futtatási idő: 155 ms

+ 940 %

$a = 'aaaaaaa';
echo 'aaaaaaa',$a,'aaaaaaa',$a

Teljes futtatási idő: 215 ms

+ 748 %

$a = 'aaaaaaa';
print 'aaaaaaa'.$a.'aaaaaaa'.$a

Teljes futtatási idő: 171 ms

+ 756 %

$a = 'aaaaaaa';
echo $a.$a.$a.$a

Teljes futtatási idő: 173 ms

+ 796 %

$a = 'aaaaaaa';
echo $a,$a,$a,$a

Teljes futtatási idő: 182 ms

+ 752 %

$a = 'aaaaaaa';
print $a,$a,$a,$a

Teljes futtatási idő: 172 ms

Következtetés:

Valójában az echo és print funkciók teljes mértékben ugyanazt a célt szolgálják és a háttérben ugyanaz a kód fut mindkét esetben. Az egyetlen észrevételünk, hogy amennyiben vesszővel választjuk el a kiírandó tagokat, esetenként minimálisan jobb teljesítményt érhetünk el.

Az =&-referencia-operátor használata $obj = $someClass->f() vs. $obj =& $someClass->f()

Célszerű a =&-referencia-operátor alkalmazása egy adott objektumon történő metódus híváskor? 1000 futtatás alapján

+ 100 %

$obj = $someClass->f();

Teljes futtatási idő: 121 ms

+ 306 %

$obj =& $someClass->f();

Teljes futtatási idő: 370 ms

Következtetés:

Hacsak nincs komoly okod a memóriaproblémák miatt aggódni, nem javasolnám az & használatát ebben az esetben.

Csak olvasást végző ciklusok:foreach() vs. for() vs. while(list() = each())

Melyik a legjobb eszköz a Hash tömbünk bejárására?

A Hash tömbünk 100 elemből áll, melynek kulcsak 24 byte-osak, értékei 10k adatot tartalmaznak.

+ 147 %

foreach($aHash as $val);

Teljes futtatási idő: 6 ms

+ 741 %

while(list(,$val) = each($aHash));

Teljes futtatási idő: 30 ms

+ 100 %

foreach($aHash as $key => $val);

Teljes futtatási idő: 4 ms

+ 818 %

while(list($key,$val) = each($aHash));

Teljes futtatási idő: 33 ms

+ 247 %

foreach($aHash as $key=>$val) $tmp[] = $aHash[$key];

Teljes futtatási idő: 10 ms

+ 935 %

while(list($key) = each($aHash)) $tmp[] = $aHash[$key];

Teljes futtatási idő: 38 ms

+ 347 %

Kulcs-érték tömbök kinyerésével: foreach($aHash as $key[]=>$val[]);

Teljes futtatási idő: 14 ms

+ 371 %

Kulcs-érték tömbök kinyerésével: array_keys() / array_values()

Teljes futtatási idő: 15 ms

+ 418 %

$key = array_keys($aHash);
$size = sizeOf($key);
for ($i=0; $i<$size; $i++) $tmp[] = $aHash[$key[$i]];

Teljes futtatási idő: 17 ms

Következtetés:

Minden esetben láthattuk, hogy a foreach ciklus szignifikánsan gyorsabb a for és while ciklusoknál. Megjegyzés: Amennyiben a tömböt legelső elemétől kezdve újra kívánjuk olvasni, erősen ajánlott a reset() funkció alkalmazása, méghozzá bármely esetben.

Leírásaink azon kezdő és haladó programozóknak nyújtanak segítséget, akik már minimális szinten foglalkoztak weboldalkészítéssel. Ha szeretnél jobban elmélyülni a témában, vagy elsajátítani alapokat, még tovább fejlődni, akkor nézz körbe tanfolyam kínálatunkban, ahol a kezdőtől a profi szintig nyújtunk képzéseket a számodra.

Oszd meg barátaiddal is!

Facebook Twitter Linkedin

Elérhetőségeink

  • Címünk: 1139 Budapest, Frangepán utca 3. (1. emelet)

  • Ügyfélfogadás, beiratkozás: Hétfőtől - péntekig: 08:00-15:00

  • Telefonszámunk: 06 70 604 2060, vagy 06 1 4500 110

  • E-mail címünk:

Közösségünk