Array vs SplFixedArray

Feb 01, 2011

PHP offers eight primitive types to the user. One of them being an array. An interesting aspect of PHP arrays is that they are allocated dynamically. Thus, the following code is perfectly acceptable:

<?php 
$arr = array(1, 2, 3, 4);
$arr[50] = 50;

The first line set the first four indexes to one through four respectively. This creates an array of size four. The second line sets index fifty to the value fifty augmenting the array size by one. Indexes five through forty nine do not exist, and attempting to access a non existing element will only raise an E_Notice level error message. The dynamic allocation of arrays allows programmers to ignore out of bounds exceptions, segmentation faults, and hours of debugging, but it also leads to a slower write time because the memory locations needed to hold the new data is not already allocated.

The Standard PHP Library offers a SplFixedArray object that pre-allocates the necessary memory thereby solving the issue of slower write times.

<?php

$array = new SplFixedArray(5);
print_r($array);
Which results in (a pre-allocated array)
SplFixedArray Object
(
[0] =>
[1] =>
[2] =>
[3] =>
[4] =>
)

Creation Time

To verify this, I ran a test that writes data to an array and an SplFixedArray and measures the time for different amounts of elements.

<?php

for($size = 1000; $size < 100000; $size *= 2) {
  $f = $size;
  for($t = microtime(true), $a = array(), $i = 0; $i < $size; $i++) {
    $a[$i] = NULL;
  }
  $f .= "," . (microtime(true) - $t) . ",";

  for($t = microtime(true), $a = new SplFixedArray($size), $i = 0; $i < $size; $i++) {
    $a[$i] = NULL;
  }
  $f .= (microtime(true) - $t) . "\n";
  file_put_contents("./data.csv", $f, FILE_APPEND);
}

Write Time

It is clear that the SplFixedArray has faster a write time. However, there is a significant overhead when an object is created. To test this, I ran the same test but each time I created a new data structure. From the plot, we can see that creating an array has minimal overhead, whereas creating a new SplFixedArray object and allocating the memory takes a significant more amount of time.

<?php

$elements = 20;

for($size = 1000; $size &lt; 100000; $size *= 2) {
  $f = $size;
  for($t = microtime(true), $i = 0; $i < $size; $i++) {
    for($j = 0,$a = array(); $j < $elements; $j++ ) {
      $a[$i] = NULL;
    }
  }
  $f .= "," . (microtime(true) - $t) . ",";

  for($t = microtime(true), $i = 0; $i &lt; $size; $i++) {
    for($j = 0, $a = new SplFixedArray($elements); $j < $elements; $j++) {
      $a[$j] = NULL;
    }
  }
  $f .= (microtime(true) - $t) . "\n";     file_put_contents("./data.csv", $f, FILE_APPEND); 
}

Memory Footprint

Lastly I wanted to see how the memory usage differs between each data structure.

<?php

for($size = 1000; $size < 100000; $size *= 2) {

  $f = $size . ",";

  $t = memory_get_usage();
  for($a = array(), $i = 0; $i < $size; $i++) {
    $a[$i] = NULL;
  }

  $f .= (memory_get_usage() - $t) . ",";

  $t = memory_get_usage();
  for($a = new SplFixedArray($size), $i = 0; $i < $size; $i++) {
    $a[$i] = NULL;
  }

  $f .= ($t - memory_get_usage()) . "\n";

  file_put_contents("./data.csv", $f, FILE_APPEND);
}

Conclusion

The conclusion is one typical of Computer Science, trade-offs. If you are in an environment where you will need a few arrays with predetermined sizes, the SplFixedArray is the best choice. However, if you will be creating numerous arrays, or the size is unknown, then it is probably better to use the native PHP array.