Digitra

LINUXサーバの設定やプログラムのことなどを中心にブログを書いています。

PHPで実行時間を同時に何箇所も計測する

PHPのプログラムのどこが遅いのかデバッグするときにブレイクポイントみたいに何箇所にも計測地点を設定したいことがある。PEARのBenchmarkというライブラリがあるようなのでそれを使ってもいいのだが、クラスや関数を跨いでいたりすると面倒なのでグローバルスコープの変数を使って、以下の様なパフォーマンス計測の関数を作ってみた。


function setBenchMarker() {
    if ( !is_array($GLOBALS["benchmark"]) ) {
        $GLOBALS["benchmark"] = array();
    }
    $trace = debug_backtrace();
    $line = $trace[0]["line"];
    $file = $trace[0]["file"];
    array_push($GLOBALS["benchmark"], array("point"=>$file.":".$line, "time"=>microtime(true)));
}
function getBenchMarkResult($delim="\n") {
    $lasttime = 0;
    $lastpoint = 0;
    $retbuf = "";
    $records = $GLOBALS["benchmark"];
    foreach ( $records as $record ) {
        $point = $record["point"];
        $time  = $record["time"];
        if ( $lasttime != 0 ) {
            $retbuf .= "[".$lastpoint."]--[".$point."]  = ".sprintf('%0.5f', $time-$lasttime).$delim;
        }
        $lastpoint = $point;
        $lasttime = $time;
    }
    return $retbuf;
}

使い方

class Hoge {
    public function __construct( ){}
    public function moge() {
        setBenchMarker();
    }
}
function foo() {
    setBenchMarker();
}

setBenchMarker();
foo();
$hoge = new Hoge();
$hoge->moge();
setBenchMarker();

$bench = getBenchMarkResult();
echo $bench;
最終結果を文字列として返しているのはerror_logなどに出力することもあるだろうなので、 中でechoはしないようにしている。

実行結果例

$ ./test.php
[/home/ec2-user/test/test.php:4]--[/home/ec2-user/test/test.php:21]  = 0.087116003
[/home/ec2-user/test/test.php:21]--[/home/ec2-user/test/test.php:30]  = 0.010456085
[/home/ec2-user/test/test.php:30]--[/home/ec2-user/test/test.php:9]  = 0.000001907