有什么办法可以避免使用 array_flip 来优化性能。我正在select从数据库中执行一条语句,准备查询并执行它,并将数据作为关联数组存储在数组中,$resultCollection然后将数组op中的每个元素$resultCollection存储outputId在其中,op[]如代码所示。
我已经解释了代码,所以我的问题是如何使用 array_flip 为 array_flip 实现类似的替代方案,因为我想提高性能。
$resultCollection = $statement->fetchAll(PDO::FETCH_ASSOC);
$op = array();
//Looping through result collection and storing unicaOfferId into op array.
foreach ($resultCollection as $output)
{
$op[] = $output['outputId'];
}
//Here op array has key as 0, 1, 2...and value as id {which I am interested in}
//Flip op array to get offer ids as key
$op = array_flip($op);
//Doing a flip to get id as key.
foreach ($ft as $Id => $Off)
{
$ft[$Id]['is_set'] = isset($op[$Id]);
}
Run Code Online (Sandbox Code Playgroud)
我添加此答案是因为您在标题“性能改进”中提到了。
您应该继续使用array_flip(). 与foreach循环相比,在性能方面,它的处理速度要快得多,尤其是在大型数组上(可能是因为它的本机性质)。性能在小阵列中几乎可以忽略。然而,赢家是array_flip()。总是。
我测试的结果(PHP 7.4,Fedora 32 工作站):
Testing an array with 10 elements:
Average time for array_flip(): 3.0E-5
Average time for foreach: 7.0E-5
How much array_flip() is faster: 105%
Testing an array with 100 elements:
Average time for array_flip(): 0.00018
Average time for foreach: 0.00038
How much array_flip() is faster: 114%
Testing an array with 1000 elements:
Average time for array_flip(): 0.00138
Average time for foreach: 0.00363
How much array_flip() is faster: 163%
Testing an array with 10000 elements:
Average time for array_flip(): 0.01443
Average time for foreach: 0.03644
How much array_flip() is faster: 152%
Testing an array with 100000 elements:
Average time for array_flip(): 0.15642
Average time for foreach: 0.37017
How much array_flip() is faster: 136%
Testing an array with 1000000 elements:
Average time for array_flip(): 1.38271
Average time for foreach: 3.75081
How much array_flip() is faster: 171%
Run Code Online (Sandbox Code Playgroud)
你看到了吗?大约array_flip()快 2.5 倍。此外,array_flip()当数组变大时,它的性能似乎略有提高。所以,忘记foreach。即使有 JIT 的帮助?继续阅读...
是的,但并非如您所料。这是 PHP 8.0.0-beta2 的结果,启用了 JIT ( opcache.jit = 1235, opcache.jit_buffer_size = 100M):
Testing an array with 10 elements:
Average time for array_flip(): 6.0E-5
Average time for foreach: 4.0E-5
How much array_flip() is faster: -29%
Testing an array with 100 elements:
Average time for array_flip(): 0.00014
Average time for foreach: 0.00025
How much array_flip() is faster: 82%
Testing an array with 1000 elements:
Average time for array_flip(): 0.00124
Average time for foreach: 0.00249
How much array_flip() is faster: 100%
Testing an array with 10000 elements:
Average time for array_flip(): 0.01201
Average time for foreach: 0.02412
How much array_flip() is faster: 100%
Testing an array with 100000 elements:
Average time for array_flip(): 0.14584
Average time for foreach: 0.25029
How much array_flip() is faster: 71%
Testing an array with 1000000 elements:
Average time for array_flip(): 1.26789
Average time for foreach: 2.54315
How much array_flip() is faster: 100%
Run Code Online (Sandbox Code Playgroud)
你可以注意到正在发生的事情。所以:
JIT 让一切变得更快。对于array_flip(),它大约提高了 10-20% 的性能,对于foreach循环,大约提高了 30-40%。因此,它比内部函数更能提高本机 PHP 代码的性能,这在意料之中。
由于前面的说明,这两种方法之间的差异减少了,尽管array_flip()快了近 2 倍。所以,JIT 很棒,但它不是一个超级神奇的东西。
所以,不考虑你的 PHP 版本和配置,内部函数大多更快。再次,使用array_flip().
这是我测试的(您可以随意配置变量):
// The ratio of array size being increased
$arraySizeBase = 10;
// Limits of the exponention of the array size
$arraySizePowerMin = 1;
$arraySizePowerMax = 6;
// Number of tests being run within one time capture
$iterationsCount = 100;
// Number of time capture repeats
$repeatCount = 20;
// Precision of rounded result
$precision = 5;
// Array values limits
$minVal = 0;
$maxVal = 10000;
function printTime(callable $x, string $title)
{
global $iterationsCount, $repeatCount, $precision;
$tests = [];
for ($i = 0; $i < $repeatCount; $i++) {
$startTime = microtime(true);
for ($j = 0; $j < $iterationsCount; $j++) {
$x();
}
$tests[] = microtime(true) - $startTime;
}
$averageTime = array_sum($tests) / $repeatCount;
echo " Average time for $title: ", round($averageTime, $precision), PHP_EOL;
// To be used to calculate ratio
return $averageTime;
}
$arraySizeMin = $arraySizeBase ** $arraySizePowerMin;
$arraySizeMax = $arraySizeBase ** $arraySizePowerMax;
for ($i = $arraySizeMin; $i <= $arraySizeMax; $i *= $arraySizeBase) {
// Filling the array with some random stuff
echo "Testing an array with $i elements:", PHP_EOL;
$array = array_fill(0, $i - 1, random_int($minVal, $maxVal));
$arrayFlipTime = printTime(function () use ($array) {
$flippedArray = array_flip($array);
// Don't be crazy, clean RAM
$flippedArray = null;
}, "array_flip()");
$foreachTime = printTime(function () use ($array) {
$flippedArray = [];
foreach ($array as $key => $value) {
$flippedArray[$value] = $key;
}
// Don't be crazy, clean RAM
$flippedArray = null;
}, "foreach");
// Print a ratio in percentage
echo " How much array_flip() is faster: ",
floor(($foreachTime / $arrayFlipTime) * 100) - 100, "%",
PHP_EOL;
echo PHP_EOL;
}
Run Code Online (Sandbox Code Playgroud)