なにかでちょろっと気になったのでざっくり検証したので、軽くlog残し。
基本的に「foreachに有利な処理*1」なので、まぁ参考程度に見ていただければ。
ただ言い方を変えると「だから処理によっては(「配列を2回ぶん回す」事になるから)array_*使うと処理的には重くなるからその辺は勘案してね」って内容ではあります。
「元が1万要素ある配列」に対して
・奇数だけを抜き出して
・値を倍にする
処理をぶんまわしてみました。
先に計測結果。
10回うごかした時間と、最後に使用メモリ*2。
// array関数版(無名関数)
0.0016610622406006sec
0.0012879371643066sec
0.0011820793151855sec
0.0011670589447021sec
0.0011560916900635sec
0.0011970996856689sec
0.0011940002441406sec
0.0012528896331787sec
0.0010929107666016sec
0.0011200904846191sec
2097152
// array関数版(動的関数)
0.002579927444458sec
0.0016429424285889sec
0.0014491081237793sec
0.0013840198516846sec
0.0014119148254395sec
0.0015451908111572sec
0.0015830993652344sec
0.0015368461608887sec
0.0014801025390625sec
0.0014641284942627sec
2097152
// foreach版(動的関数)
0.00094008445739746sec
0.00081992149353027sec
0.00080585479736328sec
0.0007941722869873sec
0.00082993507385254sec
0.00081396102905273sec
0.00085997581481934sec
0.00083804130554199sec
0.00079202651977539sec
0.00078392028808594sec
2097152
// foreach版(内部べた書き)
0.00034594535827637sec
0.00023603439331055sec
0.00034213066101074sec
0.00025701522827148sec
0.00025200843811035sec
0.00022697448730469sec
0.00030303001403809sec
0.00024294853210449sec
0.00026392936706543sec
0.0002589225769043sec
2097152
おおまかに「array関数使うんなら無名関数のほうが早いっぽい*3」「foreachなら中にベタっと処理書く方が早い」。
トータルとしては「array関数よりforeachのほうが早い」(今回の処理の場合)。
array関数の無名関数については「想像してないわけじゃなかったけどでも一定の気づきがある」結果で、foreachについてはまぁ「そうだろうなぁ」くらい(関数のcall、コスト0ではないしねぇ)。
実行時間については、一番重い「array関数版(動的関数)」と一番軽い「foreach版(内部べた書き)」で、大体、7.5倍くらいの実行時間の差異があるのかな。違うっちゃぁ違うし、誤差っちゃぁ誤差だし、くらいの微妙な感じ。
「array関数版(無名関数)」と「foreach版(内部べた書き)」で、5倍弱、くらい。
なのでまぁ「エライこと巨大な配列を扱う」んなら或いは一考する要素かもしれないし、そうでなければ「誤差レベル」って気もする。
そうすると後は「今までにやってきた技術背景次第」なのかなぁ、とも。
PythonとかRubyとか、あと最近のJavaScript辺りなんかだとarray関数版的な書き方を元々しているので、そちらからの系譜の人達は、割合とarray関数版的が「読みやすい、わかりやすい」って言って好む傾向があるように思います。
おいちゃんは元々がN88-BASICからZ80aのマシン語、C言語経由で(他にいくつかあるけど)PHPに来てるので、foreachで十分に使いやすいのでforeachでいいかなぁ、くらい。
(C++のiteratorが割と色々と好き……あの「autoが使えなかった頃の死ぬるほど長い型名」含めてwww)
その辺を前提に、あとはまぁ各自お好みで(笑
最後に、確認したコードは以下の通りです。
<?php // 元ネタ作成 $awk = range(1, 10000); // やりたい処理の関数その1:奇数偶数判定 function a(int $i) : bool { return 1 === ($i & 1); } // やりたい処理関数その2:値を倍にする function b(int $i) : int { return $i * 2; } // array関数版(無名関数) function t1(array $awk) : array { return array_map(function($i) { //return $i * 2; return $i; }, array_filter($awk, function($i) { return (1 === ($i & 1)); }) ); } // array関数版(動的関数) function t2(array $awk) : array { return array_map('b', array_filter($awk, 'a')); } // foreach版(動的関数) function t3(array $awk) : array { $ret = []; foreach($awk as $v) { if (true === a($v)) { $ret[] = b($v); } } return $ret; } // foreach版(内部べた書き) function t4(array $awk) : array { $ret = []; foreach($awk as $v) { if (1 === ($v & 1)) { $ret[] = $v * 2; } } return $ret; } // 計測 for($i = 0; $i < 10; ++$i) { $t = microtime(true); t4($awk); // ここ、書き換える $t_end = microtime(true); $t = $t_end - $t; echo $t , "sec\n"; } // 使用メモリ echo memory_get_peak_usage(true) , "\n";