前から気になっていたのでやってみた。
array_map より foreach の方が速いという話を聞いたことがあるので、まあ foreach の方が速いんだろうとは思うものの、どの程度速いのか知りたかった。
というのもLaravelの collect() ヘルパーが強力過ぎて、もう普通のArrayは使いたくないとまで思ってしまったからだ。
検証方法
次のテストコードを使って計測する。
LaravelのBooting時間とか諸々ツッコミどころはあります。
<?php
use Tests\TestCase;
class SpeedTest extends TestCase
{
    public function testCollection()
    {
        collect(range(1, 1500000))->map(function ($value) {
            return $value * 2;
        })->filter(function ($value) {
            return $value > 10000;
        });
    }
    public function testForeach()
    {
        $double_me = [];
        foreach (range(1, 1500000) as $value) {
            $double_me[] = $value * 2;
        }
        $filter_me = [];
        foreach ($double_me as $key => $value) {
            if ($value > 10000) {
                $filter_me[$key] = $value;
            }
        }
    }
}
やっていることは、
1から1500000までの範囲に対し、2倍して10000より大きい要素を取得
である。間違っていたらすみませんm(_ _)m
結果
Collectionの方
vagrant@homestead:~/Code/Laravel$ php vendor/bin/phpunit tests/SpeedTest.php --filter=Collection
PHPUnit 4.8.35 by Sebastian Bergmann and contributors.
.
Time: 1.28 seconds, Memory: 262.02MB
foreachの方
vagrant@homestead:~/Code/Laravel$ php vendor/bin/phpunit tests/SpeedTest.php --filter=Foreach                                                                             
PHPUnit 4.8.35 by Sebastian Bergmann and contributors.
.
Time: 1.06 seconds, Memory: 178.00MB
やはり若干foreachの方が速い。
しかもforeachは変数を2つ使っているにも拘わらず、メモリ消費量がかなり少なかった。
内部でどう処理されているかは知らない。
所感
まあこんな大量の範囲を扱うコードは現実にはほぼ使わないだろうから、ほとんど気にすることは無いのでは。
それよりも可読性の方が大切と考える。
foreachは一旦変数に入れるから、変数のスコープをcollect()より気にしてしまう。