はじめましての方ははじめまして。
そうでない方も忘れていると思いますのではじめまして。
今回は単純にループの処理速度が知りたくなりました。
でもこの程度のことならば、すでに調べた人が何人もいるようです。
http://ameblo.jp/mingw/entry-10385952873.html
http://blog.generace.co.jp/2013/06/21/894
と思ったのですが、真逆の結論が出てしまいました。
はたして for foreach while で本当に速いのは?
ということで、以下のコードを作ってみました。
なお、 PHP 5.4 で検証しています。
$r = [0,0,0];
$range = 100000;
$c = range(0,$range-1);
for($a = 0;$a < 10;$a++){
$t = microtime(true);
for($i = 1;++$i < $range;)$i;
$r[0] += microtime(true) - $t;
$t = microtime(true);
foreach($c as $i)$i;
$r[1] += microtime(true) - $t;
$t = microtime(true);
$i = 0;
while(++$i < $range)$i;
$r[2] += microtime(true) - $t;
}
var_dump($r);
あくまでいい加減な検証なので、コーディングスタイルとか読みやすさとか、そういうのは無視しました。
(本当はワンライナーで記述しています)
処理としては、各ループで 0 ~ 99,999 までループする処理を 10 回ループして、それぞれの合計時間を計算しています。
range は処理時間が大きいらしいので、ループの外に記述しました。
結果はどうかというと、
array(3) {
[0]=>
float(0.042150497436523)
[1]=>
float(0.036016702651978)
[2]=>
float(0.023873090744019)
}
一番上から for foreach while です。
for がやや遅くて、 while がやや速いといった結果に。
while が遅いという情報が多いのですが、真逆になりました。
http://d.hatena.ne.jp/tweeeety/20130416/1366096299
ループ回数を増やすと変わるのでしょうか。
ini_set("memory_limit",-1);
$r = [0,0,0];
$range = 1000000;
$c = range(0,$range-1);
for($a = 0;$a < 10;$a++){
$t = microtime(true);
for($i = 0;++$i < $range;)$i;
$r[0] += microtime(true) - $t;
$t = microtime(true);
foreach($c as $i)$i;
$r[1] += microtime(true) - $t;
$t = microtime(true);
$i = 0;
while($i < $range)$i++;
$r[2] += microtime(true) - $t;
}
var_dump($r);
結果
array(3) {
[0]=>
float(0.5011191368103)
[1]=>
float(0.44765543937683)
[2]=>
float(0.24919891357422)
}
変わった気がしないです。
そういえば、 while が遅いとしているソースは配列処理を念頭に置いた、より実用的なものです。
ということで、配列の中身を参照してみました。
$r = [0,0,0];
$range=100000;
$c = range(0,$range-1);
for($a = 0;$a < 10;$a++){
$t = microtime(true);
for($i = 0;++$i < $range;)$c[$i];
$r[0] += microtime(true) - $t;
$t = microtime(true);
foreach($c as $i)$i;
$r[1] += microtime(true) - $t;
$t = microtime(true);
$i = 0;
while($i < $range)$c[$i++];
$r[2] += microtime(true) - $t;
}
var_dump($r);
結果
array(3) {
[0]=>
float(0.067676544189453)
[1]=>
float(0.035441637039185)
[2]=>
float(0.065758228302002)
}
while が遅くなり、 foreach が最速になりました。
ところで、前掲のページをよく見ると、 while と一緒に list や each を使っています。
これらを使うとどうなるのでしょうか。
$r=[0,0,0];
$range=100000;
$c=range(0,$range-1);
for($a=0;$a<10;$a++){
$t=microtime(true);
for($i=0;++$i<$range;)$c[$i];
$r[0]+=microtime(true)-$t;
$t=microtime(true);
foreach($c as $i)$i;
$r[1]+=microtime(true)-$t;
$t=microtime(true);
$i=0;
while(list(,$i)=each($c))$c[$i];
$r[2]+=microtime(true)-$t;
}
var_dump($r);
array(3) {
[0]=>
float(0.066687345504761)
[1]=>
float(0.0352942943573)
[2]=>
float(4.7683715820312E-5)
}
while がとんでもないことに。
ケタ違いどころか、 3 ケタも違う結果になりました。
これがバージョンの差か、マシンの差か、はたまた別の要因かは分かりません。
(いい加減なので、テストが間違っている可能性もあり)
ただ、検索結果を信じるのではなく、自分で実験するのが大事なようです。
ただし、どの結果でも for は最遅のようです。
他の言語だと一般的なループだと思うので、以外な落とし穴かもしれません。