モダンなPHPでのベンチマークの取り方

pear にも Benchmark というライブラリがあるのですが、使うのがやや面倒。

せっかく php5.3 で無名関数が利用できるので、 perl のBenchmark::timethese っぽく、簡単に実行できるようなベンチマークを作ってみた。

<?php
namespace Bench;

/**
 * ベンチマークを実行し、結果を標準出力に表示
 *
 * @param int   $cnt        実行回数
 * @param array $functions  比較する処理(クロージャ)を含む配列
 * @param closure $interbal 各処理の間に実行するクロージャ
 * @return void
 */
function run($cnt, $functions, $interbal=null) {

    $times = array();
    foreach ($functions as $name => $func) {
        $t = microtime(true);
        for($i=0;$i<$cnt;++$i) { $func(); }
        $t = microtime(true) - $t;
        $times[$name] = $t;
        
        if ($interbal) {
            $interbal();
        }
    }

    $min = min($times);
    if (0 == $min) {
        echo "failed estimate ...\n";
        return;
    }

    foreach($times as $test_name => $time){
      $par = ($time/$min)*100;
      $unit = $time / $cnt;

      printf("%-16s: %10s sec %10s sec (%0.2f%%)\n"
        , $test_name
        , sprintf("%-0.4f", $time)
        , sprintf("@ %-0.4f", $unit)
        , $par);
    }
}

例えば md5sha1 どっちが速いかなぁ とか思ったら、こんなコードでベンチマークを取れる。

  • 使用例
<?php
require 'bench.php';

$seed = str_repeat('ABC', 1024);

Bench\run(1000, array(
    'md5' => function () use($seed) {
        md5($seed);
    },
    'sha1' => function () use($seed) {
        sha1($seed);
    },
));
  • 実行結果
md5             :     0.0107 sec   @ 0.0000 sec (100.00%)
sha1            :     0.0129 sec   @ 0.0000 sec (120.94%)

2010/03/20 : プログラム修正