Is there any way I can avoid using array_flip to optimize performance. I am doing a select statement from database, preparing the query and executing it and storing data as an associative array in $resultCollection and than I have array op and for each element in $resultCollection am storing its outputId in op[] as evident from the code.
I have explained code and so my question is how can I achieve an similar alternative for array_flip with using array_flip as I want to improve performance.
$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]);
}
I'm adding this answer because you mentioned in the title "Performance Improvement".
You should continue with array_flip(). In the terms of performance compared to a foreach loop, it does things much faster, especially on large arrays (maybe because of its native nature).
The result of what I tested (PHP 8.1.5):
Testing an array with 10 elements:
Average time for array_flip(): 2.0E-5
Average time for foreach: 3.0E-5
How much array_flip() is faster: 78%
Testing an array with 100 elements:
Average time for array_flip(): 0.00011
Average time for foreach: 0.00025
How much array_flip() is faster: 137%
Testing an array with 1000 elements:
Average time for array_flip(): 0.00108
Average time for foreach: 0.00272
How much array_flip() is faster: 150%
Testing an array with 10000 elements:
Average time for array_flip(): 0.00918
Average time for foreach: 0.02429
How much array_flip() is faster: 164%
Testing an array with 100000 elements:
Average time for array_flip(): 0.10644
Average time for foreach: 0.2439
How much array_flip() is faster: 129%
Testing an array with 1000000 elements:
Average time for array_flip(): 0.93669
Average time for foreach: 2.47616
How much array_flip() is faster: 164%
Did you see that? Approximately, array_flip() is 2.5 times faster. In addition, it seems the performance of array_flip() increases slightly when the array becomes bigger. So, forget foreach. Even with the help of JIT? Read on...
Yes! Let's see (PHP 8.1.5, with tracing JIT, opcache.jit_buffer_size = 100M):
Testing an array with 10 elements:
Average time for array_flip(): 3.0E-5
Average time for foreach: 3.0E-5
How much array_flip() is faster: -3%
Testing an array with 100 elements:
Average time for array_flip(): 0.00011
Average time for foreach: 0.00011
How much array_flip() is faster: 0%
Testing an array with 1000 elements:
Average time for array_flip(): 0.00098
Average time for foreach: 0.00101
How much array_flip() is faster: 3%
Testing an array with 10000 elements:
Average time for array_flip(): 0.00955
Average time for foreach: 0.00985
How much array_flip() is faster: 3%
Testing an array with 100000 elements:
Average time for array_flip(): 0.09958
Average time for foreach: 0.10182
How much array_flip() is faster: 2%
Testing an array with 1000000 elements:
Average time for array_flip(): 0.90585
Average time for foreach: 1.03467
How much array_flip() is faster: 14%
Interesting! Notice that:
It may seem obvious for some, but tracing JIT starts becoming more useful when you start calling a particular function in a run more and more (try playing with the $iterationsCount in the code below). Also, in most cases you could ignore the performance of a single function call.
JIT made everything faster. For array_flip(), it was up to 5-10% performance increase. For foreach, it was magical: about 150% (i.e. 2.5 times faster)!
As a result of the previous note, the difference between these two methods reduced drastically. JIT is great and is improving!
Although having a JIT-enabled environment is great, internal functions mostly are faster, independent from your configurations. So, use array_flip().
This is what I tested (feel free to configure variables yourself):
// 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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With