screenshot of test output

Unserialize Performance in PHP

Today I’m writing some PHP code that will frequently need to unserialize a short array of strings. I did some informal benchmarking to find out what serialization technique could be unpacked the fastest.

unserialize() vs. json_decode() vs. explode()

explode() was the winner here for small arrays, and that’s what I need. As arrays got bigger (100 – 10,000 items), unserialize() started to shine. When the array had 100,000 members, explode() was again the fastest. json_decode() tended to be slowest in all cases. I ran the script several times, and the results were consistent.

I peeked at memory use, too, but the three routines had pretty similar memory usage, so I did not look deeper into that. Plus, for today’s application,  speed is more important than memory.

The Data

Here’s the raw output of today’s script. The little hiccup in the data at array size 100 is interesting; explode() was slower than unserialize() at that array size every time I ran the script.

The Script

This script is intended to be run on the command line.

<?php

echo "tested on:\n";
passthru( 'php --version' );
echo "\n";
runTests( array( 10, 100, 1000, 10000, 100000 ) );

function runTests( $sizes ) {
	// Gather data
	$results = array(); // $results[routine][size]
	$routines = array( 'measureExplode', 'measureUnserialize', 'measureJsonDecode' );
	foreach ( $routines as $routine ) {
		$results[ $routine ] = array();
		foreach ( $sizes as $size ) {
			$input = array_fill( 0, $size, 'fooBarBaz' );
			$set = array();
			for ( $i=0 ; $i < 3 ; $i++) {
				$set[] = $routine( $input );
			}
			$results[ $routine ][ (string) $size ] = array_sum( $set ) / count( $set );
		}
	}

	// Display results
	$column_width = 20;

	// Header row
	echo str_pad( "array size", $column_width ) .
		str_pad( "explode", $column_width ) .
		str_pad( "unserialize", $column_width ) .
		str_pad( "json_decode", $column_width ) .
		"\n";

	// Table body
	foreach ( $sizes as $size ) {
		echo str_pad( $size, $column_width );
		foreach ( $routines as $routine ) {
			echo str_pad( number_format( $results[ $routine ][ $size ], 9 ), $column_width );
		}
		echo "\n";
	}
}

function measureExplode( $arr ) {
	$arr = implode( " ", $arr );
	$start = microtime( true );
	$arr = explode( " ", $arr );
	return microtime( true ) - $start;
}

function measureUnserialize( $arr ) {
	$arr = serialize( $arr );
	$start = microtime( true );
	$arr = unserialize( $arr );
	return microtime( true ) - $start;
}
	
function measureJsonDecode( $arr ) {
	$arr = json_encode( $arr );
	$start = microtime( true );
	$arr = json_decode( $arr );
	return microtime( true ) - $start;
}

Leave a Reply