性能改进:array_flip功能的替代方案

时间:2010-03-18 21:49:43

标签: php performance

有什么方法可以避免使用array_flip来优化性能。我正在从数据库中执行select语句,准备查询并执行它并将数据存储为$resultCollection中的关联数组,而不是数组op以及{{1}中的每个元素从代码中可以明显地将$resultCollection存储在outputId中。

我已经解释了代码,所以我的问题是如何使用array_flip为array_flip实现类似的替代方法,因为我想提高性能。

op[]

3 个答案:

答案 0 :(得分:3)

你应该能够使用foreach中的键作为索引,并像这样预先翻转构建数组。

    foreach ($resultCollection as $key => $output) {
        $op[ $output['outputId'] ] = $key;
    }

答案 1 :(得分:0)

好吧,因为看起来你不关心这个值,而是只考虑键的O(1)查找速度,我第一次以这种方式构建$op

foreach ($resultCollection as $output)
{
  $op[$output['outputId']] = null;
}

或者您可以查看in_array(),我不知道它的速度如何比较。(看起来像是0(n),所以不会更快)

修改

如果您想第一次创建 array_flip()后获得的内容,请按照这种方式进行。

$i = 0;
foreach ($resultCollection as $output)
{
  $op[$output['outputId']] = $i++;
}

但是在你的评论之后,我仍然不确定我是否真的“得到”你所追求的东西。

答案 2 :(得分:0)

我添加此答案是因为您在标题“性能改进”中提到了该问题。您应该继续array_flip()。就性能而言,与foreach循环相比,它的执行速度要快得多,尤其是在大型阵列上(可能是由于其本性)。在小型阵列中,性能几乎可以忽略。但是,获胜者是array_flip()。总是。

我测试的结果:

Testing an array with 1 elements:
  Average time for array_flip(): 3.8290023803711E-6
  Average time for foreach: 3.8695335388184E-6

Testing an array with 10 elements:
  Average time for array_flip(): 7.8582763671875E-6
  Average time for foreach: 1.3458728790283E-5

Testing an array with 100 elements:
  Average time for array_flip(): 4.5478343963623E-5
  Average time for foreach: 8.4021091461182E-5

Testing an array with 1000 elements:
  Average time for array_flip(): 0.00031920909881592
  Average time for foreach: 0.00091568946838379

Testing an array with 10000 elements:
  Average time for array_flip(): 0.0013899493217468
  Average time for foreach: 0.0030064821243286

Testing an array with 100000 elements:
  Average time for array_flip(): 0.0090116810798645
  Average time for foreach: 0.022410459518433

Testing an array with 1000000 elements:
  Average time for array_flip(): 0.082132298946381
  Average time for foreach: 0.22006005048752

Testing an array with 10000000 elements:
  Average time for array_flip(): 0.82163748979568
  Average time for foreach: 2.7672152614594

看到了吗? array_flip()通过使数组越来越大而变得越来越快。因此,现在使用它是一个更好的选择(将来,JIT可以帮助foreach更快地执行操作。)

我测试了什么

function printTime(callable $x, string $title = "test")
{
    $count = 1000;
    $repeat = 100;

    $tests = [];
    for ($i = 0; $i < $repeat; $i++) {
        $startTime = microtime(true);

        for ($i = 0; $i < $count; $i++) {
            $x();
        }

        $tests[] = microtime(true) - $startTime;
    }
    echo "  Average time for $title: ", array_sum($tests) / $repeat, PHP_EOL;
}

for ($i = 1; $i <= 10 ** 7; $i *= 10) {
    echo "Testing an array with $i elements:", PHP_EOL;
    $array = array_fill(0, $i - 1, random_int(0, 10000));

    printTime(function () use ($array) {
        $flippedArray = array_flip($array);
        // Don't be crazy, clean RAM
        $flippedArray = null;
    }, "array_flip()");

    printTime(function () use ($array) {
        $flippedArray = [];
        foreach ($array as $key => $value) {
            $flippedArray[$value] = $key;
        }
        // Don't be crazy, clean RAM
        $flippedArray = null;
    }, "foreach");

    echo PHP_EOL;
}