I have two arrays with unique numeric keys. How can I merge them faster?
3 Answers
The most important thing is code legibility. Such micro-optimisations are generally a mistake as you should write the cleanest code you can, then optimise it by profiling it.
If you are looking to speed things up or analyse time taken I suggest using xdebug, and something like cachegrind for looking at the output.
2 Comments
I find results to be inconclusive with the following test:
$n = 1_000_000;
echo 'Changed value is not overwritten:' . PHP_EOL;
$a = [
'static' => 0,
];
$start = microtime(true);
for ($i = 0; $i < $n; $i++) {
$a = $a + [
'dynamic' => $i,
];
}
$end = microtime(true);
$first = $end - $start;
echo 'union: ' . ($first) . PHP_EOL;
$b = [
'static' => 0,
];
$start = microtime(true);
for ($i = 0; $i < $n; $i++) {
$b = array_merge([
'dynamic' => $i,
], $b);
}
$end = microtime(true);
$second = $end - $start;
echo 'merge: ' . ($second) . PHP_EOL;
print_results($first, $second);
echo 'Changed value is overwritten:' . PHP_EOL;
$c = [
'static' => 0,
];
$start = microtime(true);
for ($i = 0; $i < $n; $i++) {
$c = [
'dynamic' => $i,
] + $c;
}
$end = microtime(true);
$first = $end - $start;
echo 'union: ' . ($first) . PHP_EOL;
$d = [
'static' => 0,
];
$start = microtime(true);
for ($i = 0; $i < $n; $i++) {
$d = array_merge($d, [
'dynamic' => $i,
]);
}
$end = microtime(true);
$second = $end - $start;
echo 'merge: ' . ($second) . PHP_EOL;
print_results($first, $second);
function print_results($first, $second):void {
if ($first < $second) {
$percent = number_format(100 * ($second / $first - 1), 2) . '%';
echo '+ is ' . $percent . ' faster than array_merge' . PHP_EOL . PHP_EOL;
return;
}
$percent = number_format(100 * ($first / $second - 1), 2) . '%';
echo 'array_merge is ' . $percent . ' faster than +' . PHP_EOL . PHP_EOL;
}
Results 1 (most often, but not decisive):
Changed value is not overwritten:
union: 0.10432696342468
merge: 0.11506199836731
+ is 10.29% faster than array_merge
Changed value is overwritten:
union: 0.11133003234863
merge: 0.11170411109924
+ is 0.34% faster than array_merge
Results 2 (quite often):
Changed value is not overwritten:
union: 0.11403703689575
merge: 0.1212010383606
+ is 6.28% faster than array_merge
Changed value is overwritten:
union: 0.11069583892822
merge: 0.10777497291565
array_merge is 2.71% faster than +
Results 3 (rare):
Changed value is not overwritten:
union: 0.12785387039185
merge: 0.11510610580444
array_merge is 11.07% faster than +
Changed value is overwritten:
union: 0.10895609855652
merge: 0.10755109786987
array_merge is 1.31% faster than +
Conslusion
Use whichever one is used all throughout your codebase or refactor them all to the one you find more readable. For me that's the array union operator (+). Note that both yield the same result (given you correctly change the order of operands) ONLY for associative array.
+operator do subtly different things, so you can't simply compare speed