LoginSignup
5
5

More than 5 years have passed since last update.

array_walk的なことを色んな方法でやる

Last updated at Posted at 2014-12-19

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が早いけど、差はかなり縮まりました。
もっと上手いやり方や、他のやり方のメリットデメリットなど、何でもご教示下さい。

5
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5