有什么方法可以避免使用array_flip来优化性能。我正在从数据库中执行select
语句,准备查询并执行它并将数据存储为$resultCollection
中的关联数组,而不是数组op
以及{{1}中的每个元素从代码中可以明显地将$resultCollection
存储在outputId
中。
我已经解释了代码,所以我的问题是如何使用array_flip为array_flip实现类似的替代方法,因为我想提高性能。
op[]
答案 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;
}
或者您可以查看(看起来像是0(n),所以不会更快)in_array()
,我不知道它的速度如何比较。
如果您想第一次创建 在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;
}