PHP の素朴な疑問とか
2007-12-14
PHPを良く知らない人がPHPを語るときは気をつけたほうがいいかもしれない - ito.tetsunosuke/notebookより。
for($i=0; $i < count($array); $i++) { ... }
みたいなコードはどうにかならんのかね。こういう入門書が多くてガチで困る。
$cnt = count($array); for($i=0; $i < $cnt; $i++) { ... }
を推奨。
C の場合はコンパイラが前者のコードを後者のコードに最適化するって何かで読んだ気がする…けど覚えてない。
ついでなので、 foreach を使う版も試してみた。 これもどこかで読んだ記憶があるけど、インデックスにアクセスするよりも直接変数を参照した方が早いという。 C の本だったか、 Perl の本だったか…。 PHP だったら foreach だね。 個人的には for と $i を使う機会は少ないなぁ。2つの配列を同時に回すときくらい?
foreach ($item as $array) { ... }
気になったのでベンチマークとって比較してみた。 結果は以下の通り。 foreach が一番速い (19.61%) けど count を毎回呼ぶかどうかほどの違い (55.94% と 24.36%) はなかった。 フツーに使う場合はどっちを foreach でも for でもそんなに影響ないかも。
--------------------------------------------------------------------------
marker time index ex time perct
--------------------------------------------------------------------------
Start 1197579015.04900200 - 0.00%
--------------------------------------------------------------------------
use count() every time 1197579015.27005700 0.221055 55.94%
--------------------------------------------------------------------------
use count() only first time 1197579015.36633500 0.096278 24.36%
--------------------------------------------------------------------------
use foreach 1197579015.44383600 0.077501 19.61%
--------------------------------------------------------------------------
Stop 1197579015.44416700 0.000331 0.08%
--------------------------------------------------------------------------
total - 0.395165 100.00%
--------------------------------------------------------------------------
PHP5.2.1 (cli) を VMware 上で動作させた。 サンプルコードは以下の通り。
<?php
require_once('Benchmark/Timer.php');
$sum = 0;
$array = array();
for ($i = 0; $i < 100000; $i++) {
$array[$i] = $i;
}
$timer = new Benchmark_Timer(TRUE);
// 毎回 count() を呼び出す
$sum = 0;
for ($i = 0; $i < count($array); $i++) {
$sum += $array[$i];
}
$timer->setMarker('use count() every time');
// 初回のみ count() を呼び出す
$sum = 0;
$count = count($array);
for ($i = 0; $i < $count; $i++) {
$sum += $array[$i];
}
$timer->setMarker('use count() only first time');
// foreach を使う
$sum = 0;
foreach ($array as $item) {
$sum += $item;
}
$timer->setMarker('use foreach');
$timer->display();
Pear::Benchmark も初めて使ったよ。
$ sudo pear install benchmark
で使えるようになる。