Recently I’ve been trying to cache more and more stuff – mostly to speed things up. All was well, while I was storing relatively small numbers of data – because (as you’ll see below) my approach was a little flawed.
Random background – I use Zend_Cache, in a sort of wrapped up local ‘Cache’ object, because I’m lazy. This uses Zend_Cache_Backend_File for storage of data, and makes sure e.g. different sites (dev/demo/live) have their own unique storage location – and also that nothing goes wrong if e.g. a maintenance script is run by a different user account.
My naive approach was to do e.g.
$cached_data = $cache->load('lots_of_stuff'); if(!empty($cached_data)) { if(isset($cached_data[$key])) { return $value; } } else { // calculate $value $cached_data[$key] = $value; $cache->save($cached_data, $cache_key); } return $value;
The big problem with this is that the $cached_data array tends to grow quite large; and PHP spends too long unserializing/serializing. The easy solution for that is to use more than one cache key. Problem mostly solved.
However, if the site is performing a few thousand calculations, speed of [de]serialisation is still gong to be an issue – even if the data involved is in small packets. I’d already profiled the code with xdebug/kcachegrind and could see PHP was spending a significant amount of time performing serialisation – and then remembered a presentation I’d seen (http://ilia.ws/files/zendcon_2010_hidden_features.pdf – see slides 14/15/16 I think) at PHPBarcelona covering Igbinary (https://github.com/phadej/igbinary)
Once you install the extension –
phpize ./configure make cp igbinary.so /usr/lib/somewhere #add .ini file to /etc/php5/conf.d/
You’ll have access to igbinary_serialize() and igbinary_unserialize() (I think ‘make install’ failed for me, hence the manual cp etc).
I did a random performance test based on this and it seems to be somewhat quicker than other options (json_encode/serialize) – this was using PHP 5.3.5 on a 64bit platform. Each approach used the same data structure (a somewhat nested array); the important things to realise are that igbinary is quickest and uses less disk space.
JSON (json_encode/json_decode):
- JSON encoded in 2.18 seconds
- JSON decoded in 9.83 seconds
- serialized “String” size : 13993
Native PHP :
- PHP serialized in 2.91 seconds
- PHP unserialized in 6.43 seconds
- serialized “String” size : 20769
Igbinary :
- WIN igbinary serialized in 1.60 seconds
- WIN igbinrary unserialized in 4.77 seconds
- WIN serialized “String” Size : 4467
The performance testing bit is related to this Stackoverflow comment I made on what seemed a related post
One Reply to “PHP Serialization & igbinary”