HTML Logo by World Wide Web Consortium (www.w3.org). Click to learn more about our commitment to accessibility and standards.

PHP performance: array appending

PHP performance: array appending Warning: this is a pretty technical blog post!

Something I've always wondered about with PHP, is how to efficiently append one array to another. There is no built in way to do it directly, so you need to choose something a bit inefficient:
  1. Do a loop, doing a single append in each loop (seems slow because PHP has to run the loop as PHP opcodes, when a native implementation could be in pure C).
  2. As with '1' except use a functional programming technique – 'map' an append operation over the array being merged in (seems slow because it's now having to invoke a PHP function for each list element, and PHP function calls are slow).
  3. Use array_splice (it's hard to tell at first, but this function has a superset of the functionality we need – yet that may mean it is inefficient doing specifically just what we want it to do).
  4. Use array_merge on both arrays and reassign the operation result back to our destination array (inefficient because it is having to create a new array rather than doing a merge onto an existing one)
  5. Use "+=", however this only works if both arrays have different sets of keys, which is unrealistic in our scenario. We'll include it as a baseline anyway.

I thought 'array_splice' would be faster, but I really needed to test this. The results surprised me…
TIME FOR 1: 0.00004 seconds
TIME FOR 2: 0.00011 seconds
TIME FOR 3: 0.00005 seconds
TIME FOR 4: 0.00007 seconds
TIME FOR 5: 0.00002 seconds
The naive loop is the quickest, and the 'array_splice' implementation is slightly slower.

Here's the code to prove it if anyone wants to run this themselves:

Code

<?php

header('Content-type: text/plain');

$iterations=1000;
for ($i=1;$i<=5;$i++)
{
   $start=microtime(true);
   for ($j=0;$j<$iterations;$j++)
   {
      $a=array_fill(0,100,'');
      $b=array_fill(100,100,'');

      $func='technique_'.strval($i);
      $func($a,$b);
   }
   $end=microtime(true);

   echo 'TIME FOR '.strval($i).': '.number_format(($end-$start)/floatval($iterations),5).' seconds'."\n";
}

// Our 4 possible array append techniques...

function technique_1(&$a,&$b)
{
   foreach ($b as $x)
   {
      $a[]=$x;
   }
}

function func($value) { $GLOBALS['A'][]=$value; };
function technique_2(&$a,&$b)
{
   $GLOBALS['A']=$a;
   array_map('func',$b);
}

function technique_3(&$a,&$b)
{
   array_splice($a,count($a),0,$b);
}

function technique_4(&$a,&$b)
{
   $a=array_merge($a,$b);
}

function technique_5(&$a,&$b)
{
   $a+=$b;
}

Technique '2' could be coded faster on PHP5.3+ by using closures, but I doubt that would give much gain. Technique '3' can be sped up a little if we hard-code the input array length (one could imagine we may find a way to optimise an assumption like that in), which makes it 11% faster than technique '1'.

Interestingly I first made this blog post with a mistake in my code, and it showed 'array_merge' and 'array_splice' as much slower. This was because I had each of the test iterations compounding the length of $a – it shows array_merge and array_splice are performance-bound based on the length of the first array (and possibly the second too, but this was not measured).

View all

Trackbacks

There have been no trackbacks yet

Edited