同じ処理が行える時、forを使うかforeachを使うか?

配列を順次読み出していくような処理を行う時など、forでもforeachでも大体同じ処理を行うことができますね。そうした場合、どちらの構文を使うべきでしょうか?
とりあえず、処理速度に優劣があるか調べてみましょう。調べてみましょうといっても、私あまりベンチ的なことはしたことがないため、マニュアルのmicrotimeの項を参考にしました。ベンチの基本はこうだ!とかもっと上手くて楽なやり方はこうだ!というのをご存じの方は是非ご教示願えればと思います。

[php]
// マニュアルからそのまんまの、microtimeを取得する関数。
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}

// for文を使った処理。
function usefor()
{
$a = range(1,10000);
$sum = 0;
for ($i = 0,$length = count($a); $i < $length; $i++) {
$sum += $a[$i];
}
echo($sum . ",");
}

// foreach文を使った処理。
function useforeach()
{
$a = range(1,10000);
$sum = 0;
$i = 0; // forのハンデとならないように、カウンタを進めてみます。
foreach ($a as $val) {
$i++;
$sum += $val;
}
echo($sum . ",");
}

// for文、foreach文ともに10回実行し、平均値実行時間を取得。
$sum = 0;
for ($i = 0; $i < 10; $i++) {
$time_start = microtime_float();
usefor();
$time_end = microtime_float();
$sum += $time_end - $time_start;
}
echo("

for平均:” . $sum / 10 . “

“);

$sum = 0;
for ($i = 0; $i < 10; $i++) {
$time_start = microtime_float();
useforeach();
$time_end = microtime_float();
$sum += $time_end - $time_start;
}
echo("

foreach平均:” . $sum / 10 . “

“);

?>
[/php]

1~10000までの数値が入った配列から値を取り出し、加算していくという単純な処理です。配列から中身を取り出すのはforでもforeachでも同じように可能です。結果はこうなりました。

50005000,50005000,50005000,…
for平均:0.0321362018585

50005000,50005000,50005000,…
foreach平均:0.0234318971634

若干差はあるものの、ほぼ変わりませんね。foreachのほうが遅くなる場合もあります。実行する順番を逆にしてもそれほど差はでません。

速度に差が無いのであれば、私のオススメはforeachです。その理由はコードのミスが減る(かもしれない)からです。全ての配列を操作する、といった構文を作る際に、forだと、

  • for ($i = 0; $i < $length; $i++) {…
  • なのか

  • for ($i = 0; $i <= $length; $i++) {…
  • なのか迷ってしまったり、間違いに気づかなかったりする場合があったりしませんか? foreachのようなイテレータ操作ならこういうミスはまず無いですから。

    と、長々と書いてきたワリにはあまり大したことの無い話で申し訳ありません(^_^;)

    ちなみに、よく言われることですが、
    [php]
    for ($i = 0; $i < count($a); $i++) {
    $sum += $a[$i];
    }
    [/php]
    のようなfor文の条件評価にcount()を使ったりすると、毎回count()が発生してしまいます。最初の実験スクリプト中のfor文を上記のようにcount()で条件判定に変更した結果は

    50005000,50005000,…
    for平均:1.1242749691

    50005000,50005000,…
    foreach平均:0.0304559707642

    このように、とても遅くなってしまうので気をつけましょう。

    関連する記事:

    Powered by

    Leave a Comment


    NOTE - You can use these HTML tags and attributes:
    <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">