foreachでぶん回ししている箇所をもっと効率いい方法で回せないのかな?
と気になったのでメモ。
PHPマニュアルのコメントに、ソース等そのまま乗っておりますのでそちらも併せてご覧下さい。
補足
このコードではwhileは一回しかループしておらず、実際はforeachの方が早いとのこと、
以降の記事でngyukiさんが解説してくれております!
ありがとうございますー!
前提
- データを整形する関数(下記)を配列の各要素に実行する
-
array_walk
,while
,foreach
でそれぞれ時間を計測する - 子要素を千個持った一次元配列一万個でテスト
arrayの作成、初期値設定、時間計測等の関数
function test($function, $count = 10000, $arrayElements = 1000) {
echo $function, ' ... ';
$array = array_fill(0, $arrayElements, "some text value");
$timer = microtime(true);
for( $i = 0; ++$i < $count; )
$function($array, 'some_function', 'some user data');
printf("%.3f sec\n", microtime(true) - $timer);
return $array;
}
配列の各要素に実行する関数
$value
は"some text data"
という文言が入っているので、
$key => $userData
という文言へと整形します。
($userData
は"some user data"
固定)
function some_function(&$value, $key, $userData) {
$value = "$key => $userData";
}
ex)
array( 0 => "some user data", 1 => "some user data");
array_walk
標準関数なので省略
while(list($key, $value) = each($array))
listで$key
と$value
を取得しながらeach
でポインタを進める。
listは遅いと聞いたことがあったのでこれが一番遅いかな?と予想していました。
function array_walk_list_each(&$array, $function, $userData = null) {
while ( list($key, $value) = each($array) )
$function($array[$key], $key, $userData);
}
foreach($valueを使用)
シンプルだしわかりやすい。保守的な意味でも。
function array_walk_foreach1(&$array, $function, $userData = null) {
foreach ($array as $key => &$value )
$function($value, $key, $userData);
}
foreach($valueの代わりに$array[$key]を使用)
$value
を使わないと早くなるとかあるんだろうか。
聞いたことがないし逆に遅くなりそうな気がします。
function array_walk_foreach2(&$array, $function, $userData = null) {
foreach ($array as $key => $value )
$function($array[$key], $key, $userData);
}
結果
array_walk ... 7.902472 sec
array_walk_list_each ... 0.010065 sec
array_walk_foreach1 ... 7.324589 sec
array_walk_foreach2 ... 8.251175 sec
while
早すぎない!?!???!!!
そしてやっぱりforeach
なら$value
は素直に取得したほうが早いよう。
意外なのはarray_walk
の遅さ。普通にforeach
で回したほうが早いという…。
小規模データでもやっぱりwhileが早いけど、差はかなり縮まりました。
もっと上手いやり方や、他のやり方のメリットデメリットなど、何でもご教示下さい。