Performance comparison between a regular PHP array and SplFixedArray

One of the key questions we encountered in the last section was, why should we use SplFixedArray instead of PHP arrays? We are now ready to explore the answer. We came across the concept that PHP arrays are actually not arrays rather than hash maps. Let us run a small example code in PHP 5.x version to see the memory usage of a PHP array.

Let us create an array with 100,000 unique PHP integers. As I am running a 64 bit machine, I expect each integer to take 8 bytes each. So we will have around 800,000 bytes of memory consumed for the array. Here is the code:

$startMemory = memory_get_usage();
$array = range(1,100000);
$endMemory = memory_get_usage();
echo ($endMemory - $startMemory)." bytes";

If we run this code in our command prompt, we will see an output of 14,649,040 bytes. Yes, it is correct. The memory usage is almost 18.5 times more than what we have planned for. That means, for each element in the array an overhead of 144 bytes (18 * 8 bytes) for one PHP array. Now, where does this extra 144 bytes come from and why does PHP utilize so much extra memory for each array element? Here is an explanation of the extra bytes used by a PHP array:

This diagram shows how a PHP array works internally. It stores data in a bucket to avoid collision and to accommodate more data. To manage this dynamic nature, it implements both a doubly linked list and hash table internally for array. Eventually, it costs lots of extra memory space for each individual elements in the array. Here is the breakdown of the memory consumption of each element based on the PHP array implementation code (C code):

32 bit

64 bit

zval

16 bytes

24 bytes

+ cyclic GC info

4 bytes

8 bytes

+ allocation header

8 bytes

16 bytes

zval (value) total

28 bytes

48 bytes

bucket

36 bytes

72 bytes

+ allocation header

8 bytes

16 bytes

+ pointer

4 bytes

8 bytes

bucket (array element) total

48 bytes

96 bytes

Grand total (bucket+zval)

76 bytes

144 bytes

In order to understand the internal structure of a PHP array, we need to study in depth about PHP internals. It is beyond the scope of this particular book. A good recommended read is: https://nikic.github.io/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html

With the new PHP 7 version, there is a very big improvement in the PHP array and how it is constructed internally. As a result, the 144 bytes overhead on each element has come down to 36 bytes only. That is a big improvement and it is applicable for both 32 bit and 64 bit OS. A comparison chart, having a range of 100,000 items in an array, is shown as follows:

$array = Range(1,100000)

32 bit

64 bit

PHP 5.6 or below

7.4 MB

14 MB

PHP 7

3 MB

4 MB

So, in other words, PHP 7 has an improvement factor of 2.5 times for 32 bit and 3.5 times for 64 bit system for array storage. That is a really good improvement. But this was all about a PHP array, what about SplFixedArray? Let us run the same example using SplFixArray in both PHP 7 and PHP 5.x:

$items = 100000; 
$startMemory = memory_get_usage();
$array = new SplFixedArray($items);
for ($i = 0; $i < $items; $i++) {
$array[$i] = $i;
}
$endMemory = memory_get_usage();

$memoryConsumed = ($endMemory - $startMemory) / (1024*1024);
$memoryConsumed = ceil($memoryConsumed);
echo "memory = {$memoryConsumed} MB ";

We have written the memory consumption functionality of a SplFixedArray here. If we just change the line $array = new SplFixedArray($items); to $array = [];, we will have the same code running as for a PHP array.

The benchmark result can vary from machine to machine as there can be different OS, memory size, debugger on/off, and so on. It is always suggested to run the codes in your own machines to generate a similar benchmark for comparisons.

Here is a comparison of memory consumption of a PHP array and SplFixedArray for an array with 100,000 integers in a 64 bit system:

100,000 items

Using PHP array

SplFixedArray

PHP 5.6 or below

14 MB

6 MB

PHP 7

5 MB

2 MB

Not only in memory usage, SplFixedArray is also faster in execution compared to general PHP array operations such as accessing value, assigning value, and so on.

Though we use the  SplFixedArray object with [] just like the array, PHP array functions will not be applicable for SplFixedArray. We cannot directly apply any PHP array functions such as array_sum, array_filter, and so on.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset