For each solution, I used 3 set of tests (each run 10 times, to get an average result) :

  • connection and increment of a simple value, only to compute the connection cost
  • connection and set / get of 10000 numerical values
  • connection and set / strlen of ~2700 big values (all the man pages, section 1)

1. redis extension

Required components:

  • redis extension
  • RPM package: php-pecl-redis

Code sample:

<?php
$time = microtime(true);
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
printf("Value = %d\n", $redis->incr("foo"));
$time = microtime(true)-$time;
printf("Done in %.6f\n", $time);

Full tests source code used: redis.txt.

Results :

  • Connection: 0.000299
  • Set / get: 0.277000
  • Set / strlen: 0.110900

This the most known and used solution, sadly, I have some doubts about the code quality of this extension.

2. Predis library

Required components

  • Predis library
  • RPM package: php-nrk-Predis

Code sample:

<?php
require 'Predis/Autoloader.php';
Predis\Autoloader::register();
$time = microtime(true);
$redis = new Predis\Client(['host' => '127.0.0.1', 'port' => 6379]);
printf("Value = %d\n", $redis->incr("foo"));
$time = microtime(true)-$time;
printf("Done in %.6f\n", $time);

Full tests source code used: predis.txt (need to comment out the constructeur call).

Results :

  • Connection: 0.001890
  • Set / get: 0.375500
  • Set / strlen: 11.445000

No surprise, a pure PHP implementation is much slower. Of course this is related to library loading which penalizes the connection, then the simple requests execution (get/set) is rather acceptable.

3. phpiredis extension

Required components:

  • phpiredis extension
  • RPM packages: php-phpiredis, hiredis

Code sample:

<?php
$time = microtime(true);
$redis = phpiredis_connect('127.0.0.1', 6379);
printf("Value = %d\n", phpiredis_command($redis, "INCR foo"));
$time = microtime(true)-$time;
printf("Done in %.6f\n", $time);

Full tests source code used: phpiredis.txt.

Results:

  • Connection: 0.000241
  • Set / get: 0.288100
  • Set / strlen: 0.105000

Results are close to the redis extension ones.

Sadly this extension, however already old, is still under development (beta). Its code is very simple (~1000 lines vs ~20000 for redis). and using the hiredis library seems (to me) far more sane and simple to maintain for a long term.

4. Predis library with the phpiredis extension

Required components

  • Predis library
  • phpiredis extension
  • RPM packages: php-nrk-Predis, php-phpiredis, hiredis

Code sample:

<?php
require 'Predis/Autoloader.php';
Predis\Autoloader::register();
$time = microtime(true);
$redis = new Predis\Client(['host' => '127.0.0.1', 'port' => 6379], ['connections' => ['tcp' => 'Predis\\Connection\\PhpiredisSocketConnection']]);
printf("Value = %d\n", $redis->incr("foo"));
$time = microtime(true)-$time;
printf("Done in %.6f\n", $time);

Full tests source code used: predis.txt.

Results:

  • Connection: 0.001795
  • Set / get : 0.378900
  • Set / strlen : 0.145300

As stated in the documentation, the Predis library take a huge benefit when phpiredis extension is used for big data sets. The tests results are very acceptable.

5. Conclusion

Up to you for a choice reading the results.

I will be tempted to prefer the phpiredis extension when speed is the main priority, and the Predis library for code beauty. This association seems rational, also followed by some other projects (e.g. mongo => mongodb) the extension is reduce to a minimal code, using a dedicated system library (hiredis here) and only take care of low level part (protocol), where performance is needed, and the library provides the high level part to the developer.

I plan to try to give some help to the phpiredis extension author so a version can be published soon, preferably on PECL forge, to give it more visibility. And then I will probably submit a review for official Fedora/EPEL repositories.