PHP Performance of removing an element off the beginning of an array

Being the performance nut that I am I decided to do some micro benchmarks on the various options of removing an element off the beginning of an array. There are several ways to do this, here is the code and the results:


function array_shift_test() {

  // Create arrays with 100000 elements
  $array_1 = array();
  for ($i = 0; $i < 100000; $i++) {
    $array_1[] = rand();
  }
  $array_2 = $array_3 = $array_4 = $array_5 = $array_1;

  $output = '';

  // Remove the last 1000 elements using array_pop.
  $start = microtime(true);
  for ($i = 0; $i < 1000; $i++) {
    array_pop($array_1);
  }
  $stop = microtime(true);
  $output .= sprintf("array_pop takes %.5f seconds\n", $stop - $start);

  // Remove the first 1000 elements using array_shift.
  $start = microtime(true);
  for ($i = 0; $i < 1000; $i++) {
    array_shift($array_2);
  }
  $stop = microtime(true);
  $output .= sprintf("array_shift takes %.5f seconds\n", $stop - $start);

  // Remove the first 1000 elements by reversing the array and popping 1000 elements.
  $start = microtime(true);
  $array_rev = array_reverse($array_3);
  for ($i = 0; $i < 1000; $i++) {
    array_pop($array_rev);
  }
  $array_3 = array_reverse($array_rev);
  $stop = microtime(true);
  $output .= sprintf("array_reverse + array_pop takes %.5f seconds\n", $stop - $start);

  // Unset the first 1000 elements.
  $start = microtime(true);
  for ($i = 0; $i < 1000; $i++) {
    unset($array_4[$i]);
  }
  $stop = microtime(true);
  $output .= sprintf("unset takes %.5f seconds\n", $stop - $start);

  // Use each to just iterate.
  $start = microtime(true);
  for ($i = 0; $i < 1000; $i++) {
    list($key, $value) = each($array_5);
  }
  $stop = microtime(true);
  $output .= sprintf("each takes %.5f seconds\n", $stop - $start);

  return $output;
}

Results (PHP 5.2.13):
array_pop takes 0.01588 seconds
array_shift takes 5.15715 seconds
array_reverse + array_pop takes 0.04179 seconds
unset takes 0.01475 seconds
each takes 0.00118 seconds

Results (PHP 5.3.2):
array_pop takes 0.01448 seconds
array_shift takes 5.01599 seconds
array_reverse + array_pop takes 0.03513 seconds
unset takes 0.01494 seconds
each takes 0.00107 seconds

each() is the clear winner here, but it comes with some caveats. each() only advances the pointer, it doesn't actually remove an element. This is fine if you are doing complicated iterations over the array, but not much else. It's also not as clear to the reader as to what is going on in the code. Therefore I'd recommend using unset() unless this is an extremely performance critical path. Stay away from array_shift() at all costs (it needs to re-index the array).

There's also the question of memory usage. unset() and each() don't actually remove the element from memory, each() just advances a pointer and unset() just removes access to the element. So you should keep this in mind if your array is very memory intensive.

Other reading:
http://drupal.org/node/172764
http://kb.ucla.edu/articles/performance-of-array_shift-and-array_pop-in-...