Digging into the PHP 5.3 SplDoublyLinkedList (part 1)

During my recent adventures of exploring the new offerings of PHP 5.3, I dug into the SplDoublyLinkedList class.

It appears as if the main strength of SplDoublyLinkedList is the memory usage, with all the nifty functions as an extra benefit. I decided to write some quick tests to compare the memory usage with the standard array population techniques.

Our first tests use the standard array population techniques:

$max = 500;
$mems = array();
$mems[] = memory_get_peak_usage();
$time_start = microtime(true);
$arr = array();
$mems[] = memory_get_peak_usage();

foreach(range(0,$max - 1) as $n) {
    $mems[] = memory_get_peak_usage();
    $arr[] = $n;
}
$mems[] = memory_get_peak_usage();

$time_end = microtime(true);
$el = $time_end - $time_start;
echo "AVG: " . (array_sum($mems)/count($mems)) . "\n";
echo "DEV: " . stats_absolute_deviation($mems) . "\n";
echo "MAX: " . max($mems) . "\n";
echo "TIME: $el\n";

The results for our first test:
AVG: 426375.33200795
DEV: 22236.20807165
MAX: 469140
TIME: 0.00060796737670898

Next we use array_push:

$max = 500;
$mems = array();
$mems[] = memory_get_peak_usage();
$time_start = microtime(true);
$arr = array();
$mems[] = memory_get_peak_usage();
foreach(range(0,$max - 1) as $n) {
    $mems[] = memory_get_peak_usage();
    array_push($arr,$n);
}
$mems[] = memory_get_peak_usage();
$time_end = microtime(true);
$el = $time_end - $time_start;
echo "AVG: " . (array_sum($mems)/count($mems)) . "\n";
echo "DEV: " . stats_absolute_deviation($mems) . "\n";
echo "MAX: " . max($mems) . "\n";
echo "TIME: $el\n";

The results for the array_push test:
AVG: 426526.36978131
DEV: 22242.520574367
MAX: 469340
TIME: 0.00081396102905273

As I had expected, array_push took a little more memory and time than the first test.

Now, the SplDoublyLinkedList test:

$max = 500;
$mems = array();
$mems[] = memory_get_peak_usage();
$time_start = microtime(true);
$dll = new SplDoublyLinkedList();
$mems[] = memory_get_peak_usage();
foreach(range(0,$max - 1) as $n) {
    $mems[] = memory_get_peak_usage();
    $dll->push($n);
}
$mems[] = memory_get_peak_usage();
$time_end = microtime(true);
$el = $time_end - $time_start;
echo "AVG: " . (array_sum($mems)/count($mems)) . "\n";
echo "DEV: " . stats_absolute_deviation($mems) . "\n";
echo "MAX: " . max($mems) . "\n";
echo "TIME: $el\n";

The results:
AVG: 420486.6640159
DEV: 19025.874083531
MAX: 457556
TIME: 0.0011141300201416

Comparing the results form the SplDoublyLinkedList test to our previous tests, we have verified that SplDoublyLinkedList does in fact take less memory during population.

While the memory usage is in fact much better, we need to take into consideration that time elapsed in comparison to our previous test. It did take more time to complete the SplDoublyLinkedList test, and I wondered how much difference it would be if we took the instantiation out of the timing period… and here are the results:
AVG:420442.75149105
DEV:19025.786782288
MAX:457512
TIME:0.00079107284545898

As we can see, removing the instantiation out of the timing does improve the timing quite a bit.

Taking this a step further, I decided to run these same tests using SplFixedArray. Although, the SplFixedArray is a different beast because it is less dynamic and less feature rich than SplDoublyLinkedList, I couldn’t help but wonder just how much faster it could be.

The SplFixedArray test:

$max = 500;
$mems = array();
$mems[] = memory_get_peak_usage();
$time_start = microtime(true);
$arr = new SplFixedArray($max);
$mems[] = memory_get_peak_usage();
foreach(range(0,$max - 1) as $n) {
    $mems[] = memory_get_peak_usage();
    $arr[$n] = $n;
}
$mems[] = memory_get_peak_usage();
$time_end = microtime(true);
$el = $time_end - $time_start;
echo "AVG: " . (array_sum($mems)/count($mems)) . "\n";
echo "DEV: " . stats_absolute_deviation($mems) . "\n";
echo "MAX: " . max($mems) . "\n";
echo "TIME: $el\n";

The results of the SplFixedArray test:
AVG: 417311.73757455
DEV: 13945.024279769
MAX: 444240
TIME: 0.00061988830566406

Wow, thats much better in both memory usage and execution time! Upon taking all of these tests in consideration, it definitely appears as if the new PHP 5.3 SPL data structures are definitely worth looking into…. just be sure to pick the one you need as it is appropriate for your situation.

Stay tuned, as I will follow up with another post going into more details of the usage of SplDoublyLinkedList.

~ by ityndall on October 27, 2010.

Leave a Reply