Help us understand the problem. What is going on with this article?

array_reduceのバグがhhvmにあるか調べる

More than 1 year has passed since last update.

報告したけど絶賛放置中wのarray_reduceの性能問題( https://bugs.php.net/bug.php?id=75533 ) 1 ですが、hhvmは実装が違うだろうから多分ないと思うので確認してみた。

型とかつけて以下のように書き換えて実行。

test_array_reduce.php:

<?hh

function test_array_reduce(int $n): void
{
    $d = range(1, $n);

    $t0 = microtime(true);
    $r = array_reduce(
            $d,
            function (&$carry, $item) {
                $carry []= $item;
                return $carry;
            },
            []
        );
    printf("%fms\n", (microtime(true) - $t0) * 1000);
}

test_array_reduce((int)$argv[1]);

test_my_reduce.php:

<?hh

function foo_reduce<T1,T2>(array<T1> $array, (function(T2, T1): T2) $func, T2 $init): T2
{
    $carry = $init;
    foreach ($array as $item) {
        $carry = $func($carry, $item);
    }
    return $carry;
}

function test_my_reduce(int $n): void
{
    $d = range(1, $n);

    $t0 = microtime(true);
    $r = foo_reduce(
            $d,
            function (&$carry, $item) {
                $carry []= $item;
                return $carry;
            },
            []
    );
    printf("%fms\n", (microtime(true) - $t0) * 1000);
}

test_my_reduce((int)$argv[1]);

結果はこんな感じで問題なし。

% hhvm test_array_reduce.php 100000
17.694950ms
% hhvm test_my_reduce.php 100000
15.845776ms
% hhvm test_array_reduce.php 200000
24.797916ms
% hhvm test_my_reduce.php 200000
23.839951ms

組み込みのarray_reduceより自分で書いた関数の方が速いのはご愛敬か?

さらにいうとfoo_reduceの中で$carryの値は$funcの呼び出し後は必ず破壊されるので保持する必要がないからさらにリファレンスカウントを1つ減らすことが可能で、そのような最適化を行えば$carryを参照渡しにしなくてもコピーが行われなくなり便利そうですが、さすがにそこまではやってないようでした。


  1. 組み込みのarray_reduceが$carryが大きな配列でcallback関数の中で書き換えを行うときに、$carryを参照渡しにしていても自分でforeach使って実装したのより遅くなることがあるという性能バグです。(array_reduceの内部で$carryへのリファレンスを1つ余分に持っているので参照で受けても余計な配列コピーが行われる模様) 

crhg
yyphp
PHPerが毎週集まり、ざっくばらんに情報交換する雑談コミュニティ
https://yyphp.connpass.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away