PHPでの配列ループ処理何通りかについてベンチマークテストを実施してみました。
対象のループ処理は、for文、foreach文、while文、array_map()関数などなどです。
対象のPHPバージョンは、8.2 / 8.3 / 8.4 です。
▼テストケース
要素数1,000,000(ひゃくまん)の1次元リスト配列(添え字0スタート連番) $a を用意します。
$a の各要素はランダムな整数とします。
$a について、単純にループを回します。
$a の各要素に1を足した最終結果の配列を返すようにします。
1回のイテレーションで実行時間の計測をします。
▼foreach文
$b = [];
foreach ($a as $v) {
$b[] = $v + 1;
}
return $b;
▼for文
$b = [];
$count = count($a);
for ($i = 0; $i < $count; $i++) {
$b[] = $a[$i] + 1;
}
return $b;
▼while文 $i++ で判定
$b = [];
$i = 0;
$count = count($a);
while ($i < $count) {
$b[] = $a[$i] + 1;
$i++;
}
return $b;
▼while文 配列ポインタcurrent()/next()を使用
$b = [];
while ($v = current($a)) {
$b[] = $v + 1;
next($a);
}
return $b;
▼while文 イテレータを使用
$iterator = new ArrayIterator($a);
$b = [];
while ($iterator->valid()) {
$b[] = $iterator->current() + 1;
$iterator->next();
}
return $b;
▼array_map()関数
return array_map(fn ($e) => $e + 1, $a);
▼array_walk()関数
$b = [];
array_walk($a, fn ($e) => $b[] = $e + 1);
return $b;
▼ベンチマークテストに使用したツール:
▼テストコード
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use Macocci7\PhpBenchmark\Benchmark;
// 配列生成
$n = 1000000;
$a = array_map(fn ($e) => rand(0, 100), range(1, $n)); // ワンライナーでスマートに見えるが高コストなおバカ処理
$iterator = new ArrayIterator($a);
Benchmark::codes([
"foreach" => function () use ($a) {
$b = [];
foreach ($a as $v) {
$b[] = $v + 1;
}
return $b;
},
"for" => function () use ($a) {
$b = [];
$count = count($a);
for ($i = 0; $i < $count; $i++) {
$b[] = $a[$i] + 1;
}
return $b;
},
"while i++" => function () use ($a) {
$b = [];
$i = 0;
$count = count($a);
while ($i < $count) {
$b[] = $a[$i] + 1;
$i++;
}
return $b;
},
"while current()/next()" => function () use ($a) {
$b = [];
while ($v = current($a)) {
$b[] = $v + 1;
next($a);
}
return $b;
},
"while Iterator" => function () use ($iterator) {
$b = [];
while ($iterator->valid()) {
$b[] = $iterator->current() + 1;
$iterator->next();
}
return $b;
},
"array_map" => function () use ($a) {
return array_map(fn ($e) => $e + 1, $a);
},
"array_walk" => function () use ($a) {
$b = [];
array_walk($a, fn ($e) => $b[] = $e + 1);
return $b;
},
], 1);
▼実行環境:
- PHP Version: 8.2.29 / 8.3.25 / 8.4.12
- OS: Ubuntu24.04.2 LTS on WSL2 (Windows11 26100.6584)
- Machine: AMD Ryzen 7 7730U(2.00GHz) / RAM 16GB / 64bit
▼実行結果
・8.2
1: foreach => Time: 0.053075 sec Avg: 0.0530750751 sec
2: for => Time: 0.070055 sec Avg: 0.0700550079 sec
3: while i++ => Time: 0.068458 sec Avg: 0.0684578419 sec
4: while current()/next() => Time: 0.003387 sec Avg: 0.0033869743 sec
5: while Iterator => Time: 0.440034 sec Avg: 0.4400339127 sec
6: array_map => Time: 0.252750 sec Avg: 0.2527501583 sec
7: array_walk => Time: 0.349774 sec Avg: 0.3497738838 sec
・8.3
1: foreach => Time: 0.042910 sec Avg: 0.0429100990 sec
2: for => Time: 0.074398 sec Avg: 0.0743980408 sec
3: while i++ => Time: 0.069607 sec Avg: 0.0696070194 sec
4: while current()/next() => Time: 0.003456 sec Avg: 0.0034558773 sec
5: while Iterator => Time: 0.442884 sec Avg: 0.4428839684 sec
6: array_map => Time: 0.257925 sec Avg: 0.2579250336 sec
7: array_walk => Time: 0.339145 sec Avg: 0.3391449451 sec
・8.4
1: foreach => Time: 0.043218 sec Avg: 0.0432181358 sec
2: for => Time: 0.070480 sec Avg: 0.0704798698 sec
3: while i++ => Time: 0.068050 sec Avg: 0.0680499077 sec
4: while current()/next() => Time: 0.003429 sec Avg: 0.0034289360 sec
5: while Iterator => Time: 0.418805 sec Avg: 0.4188048840 sec
6: array_map => Time: 0.252669 sec Avg: 0.2526688576 sec
7: array_walk => Time: 0.341707 sec Avg: 0.3417069912 sec
▼実行結果をグラフにしてみました

▼実行結果を表にまとめたもの
※「コメント」はChat-GPTによる評価(コードを見ずに勝手につけた正しくないコメント)
| ループ方法 | PHP 8.2 | PHP 8.3 | PHP 8.4 | コメント |
|---|---|---|---|---|
foreach | 0.053075 | 0.042910 | 0.043218 | 安定して高速、内部最適化済み |
for | 0.070055 | 0.074398 | 0.070480 | count()毎回呼び出しは遅め |
while i++ | 0.068458 | 0.069607 | 0.068050 | forとほぼ同等 |
while current()/next() | 0.003387 | 0.003456 | 0.003429 | 最速、内部ポインタ操作による軽量走査 |
while Iterator | 0.440034 | 0.442884 | 0.418805 | 遅い、オブジェクト生成のコスト大 |
array_map | 0.252750 | 0.257925 | 0.252669 | コールバック呼び出しのオーバーヘッド |
array_walk | 0.349774 | 0.339145 | 0.341707 | コールバック+参照渡しでやや遅い |
▼上の表を基に、バージョン毎に最速のものを基準値1.00とした場合の倍率
※Chat-GPTまとめ
| ループ方法 | PHP 8.2 | PHP 8.3 | PHP 8.4 |
|---|---|---|---|
foreach | 15.66 | 12.42 | 12.58 |
for | 20.70 | 21.53 | 20.50 |
while i++ | 20.20 | 20.14 | 19.85 |
while current()/next() | 1.00 | 1.00 | 1.00 |
while Iterator | 129.95 | 128.20 | 122.18 |
array_map | 74.53 | 74.64 | 73.66 |
array_walk | 103.29 | 97.98 | 99.64 |
▼筆者による分析
実行時のPCのタスク状況に多少左右されますが、順位の傾向は同じです。
配列ポインタを使用するwhile文が桁違いで最速!!なんとforeach文の12倍以上の速さ!
array_map()やarray_walk()等の関数系は桁違いに遅い。。
イテレータを使ったwhile文がダントツ遅い。。
やはり、配列ポインタを使うwhile文 current()/next() のループはC言語に近い動きで、PHP用の余計な処理が少ないせいで速いんですかね。
foreach文が思考停止でループするだけだから最速かと思っていましたが、そんなことはありませんでした。
for文とwhile文 $i++ はほぼ同じ。多分、$i++が入る分だけforeach文より遅いと思われ。
array_map()、array_walk()の関数系は圧倒的に高コスト(foreach文の約6倍、for文・while文の約3.5倍)。ループの各ステップで毎回コールバックの呼出が発生することが原因でしょう。
while文 イテレータ は 圧倒的に遅いarray_map()のさらに約1.7倍。。
ループのステップ毎に毎回 valid()/current()/next() の3度のメソッド呼出が祟っていることは間違いないでしょう。
▼まとめ
速い順に並べると:
1.while current()/next()
2.foreach
3.while i++
4.for
5.array_map()
6.array_walk()
7.while文 Iterator
配列ポインタを使うwhile文が最速なのは判ったけど、
見た目が美しくなくて嫌なので、foreachに走りがち。。
多分、普段はforeachで良いと思います。
パフォーマンス改善の必要に迫られたら、配列ポインタを使うwhile文にするということで。
要素数が数千程度ならarray_map()、array_walk()も全然アリだと思います。
要素数ひゃくまんで0.4秒未満ですから。
- 1
- 0
- 0
- 0


コメント