4

I have two arrays with unique numeric keys. How can I merge them faster?

7
  • 4
    Be careful that array_merge and the array + operator do subtly different things, so you can't simply compare speed Commented Jan 30, 2015 at 9:52
  • 3
    However, why don't you run some tests yourself and see if it really makes that much difference? Note that you may find the answer varies depending on the amount of data that you're working with! Commented Jan 30, 2015 at 9:52
  • php.net/manual/en/function.microtime.php Commented Jan 30, 2015 at 9:54
  • Bear in mind that the answer to the broader question this hints at is often "by doing the operation in the database, where you should be doing it"... Commented Jan 30, 2015 at 9:54
  • 1
    Is that the slowest part of your code? Commented Jan 30, 2015 at 10:04

3 Answers 3

6

10000000 iterations on PHP 7.1.5 with two small multi-dimensional arrays:

  • plus-operator (+): 1.966 seconds
  • array_merge: 9.431 seconds

So the plus operator is faster but if you have collisions, the result is different.

Sign up to request clarification or add additional context in comments.

Comments

2

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

Besides that I also dunno why people don't try by themselves to see which one is faster.
Not sure we can consider it as a micro optimisation because the difference is neat there.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.