125

多くのクラスのうち、どのクラスがより速く実行されるか (すべてが同じジョブを実行するクラス) をどのように判断できますか? それを測定するソフトウェアはありますか?

4

10 に答える 10

210

(少なくとも) 2 つのソリューションがあります。

非常に「素朴な」ものは、​​コードの一部の前後に microtime(true) を使用して、実行中に経過した時間を取得します。他の回答はそれを言っており、すでに例を挙げているので、これ以上は言いません.

これは、いくつかの命令をベンチマークする場合に適したソリューションです。たとえば、2 種類の関数を比較するようなものです。「摂動要素」が平均化されていることを確認するには、何千回も実行した方がよいでしょう。

このようなものなので、配列をシリアル化するのにかかる時間を知りたい場合:

$before = microtime(true);

for ($i=0 ; $i<100000 ; $i++) {
    serialize($list);
}

$after = microtime(true);
echo ($after-$before)/$i . " sec/serialize\n";

完璧ではありませんが、便利で、セットアップにそれほど時間はかかりません。



スクリプト全体でどの関数に多くの時間がかかるかを特定したい場合に非常にうまく機能するもう1つの解決策は、次を使用することです。

  • スクリプトのプロファイリング データを生成するためのXdebug拡張機能
  • プロファイリング データを読み取り、読み取り可能なものを提示するソフトウェア。私はそれらのうちの3つを知っています:
    • ウェブグラインド; ウェブインターフェース; 任意の Apache+PHP サーバーで動作するはずです
    • WinCacheGrind ; Windows のみ
    • KCacheGrind ; おそらく Linux と Linux ライクのみです。それは私が好むものです、ところで

プロファイリング ファイルを取得するには、 Xdebug をインストールして構成する必要があります。ドキュメントのPHP スクリプトのプロファイリングページを見てください。

私が通常行うことは、デフォルトでプロファイラーを有効にせず(非常に大きなファイルが生成され、速度が低下します)、GET データと呼ばれるパラメーターを送信して、XDEBUG_PROFILE必要なページだけのプロファイリングを有効にすることです。
私の php.ini のプロファイリング関連の部分は次のようになります。

xdebug.profiler_enable = 0              ; Profiling not activated by default
xdebug.profiler_enable_trigger = 1      ; Profiling activated when requested by the GET parameter
xdebug.profiler_output_dir = /tmp/ouput_directory
xdebug.profiler_output_name = files_names

(詳細については、ドキュメントを参照してください)

このスクリーンショットは、KcacheGrind の C++ プログラムからのものです: (ソース: sourceforge.net ) PHP スクリプトでまったく同じ種類のものを取得できます ;-) (KCacheGrind では、つまり、WinCacheGrind は KCacheGrind ほど良くありません... )http://kcachegrind.sourceforge.net/html/pics/KcgShot3Large.gif



これにより、アプリケーションで何が時間がかかるかをよく把握できます。また、すべてを遅くしている関数を特定するのに役立つ場合もあります ^^

Xdebug は、PHP が費やした CPU 時間をカウントすることに注意してください。PHP がデータベースからの応答を待っている場合 (たとえば)、動作していません。待っているだけ。したがって、Xdebug は DB リクエストにそれほど時間がかからないと判断します。
これは、PHP ではなく SQL サーバーでプロファイリングする必要があるため、...


これが役に立てば幸いです:-)
楽しんでください!

于 2009-07-29T20:11:57.357 に答える
48

簡単なことのために、私はこれを行います(PHPで):

$startTime = microtime(true);
doTask(); // whatever you want to time
echo "Time:  " . number_format(( microtime(true) - $startTime), 4) . " Seconds\n";

http://xdebug.org/のようなプロファイラーを使用することもできます。

于 2009-07-29T13:30:15.353 に答える
5

私は最近 XHProf を使用していますhttp://pecl.php.net/package/xhprof。元々は Facebook によって開発されたもので、適切な Web インターフェイスが付属しています。

于 2009-07-30T00:16:56.270 に答える
4

I'd like to share with you a self made function I use to measure the speed of any existing function up to 10 arguments:

function fdump($f_name='', $f_args=array()){

    $f_dump=array();
    $f_result='';

    $f_success=false;

    $f_start=microtime();
    $f_start=explode(' ', $f_start);
    $f_start=$f_start[1] + $f_start[0];

    if(function_exists($f_name)){

        if(isset($f_args[0])&&is_array($f_args[0])){
            if($f_result=$f_name($f_args)){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[1])){
            if($f_result=$f_name($f_args[0])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[2])){
            if($f_result=$f_name($f_args[0],$f_args[1])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[3])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[4])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[5])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[6])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[7])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[8])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[9])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[10])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8],$f_args[9])){
                $f_success=true;
            }
        }
    }
    $f_end=microtime();
    $f_end=explode(' ', $f_end);
    $f_end=$f_end[1] + $f_end[0];

    $f_time=round(($f_end - $f_start), 4);
    $f_dump['f_success']=$f_success;
    $f_dump['f_time']=$f_time;
    $f_dump['f_result']=$f_result;

    var_dump($f_dump);exit;

    //return $f_result;

}

Example

function do_stuff($arg1='', $arg2=''){
    return $arg1.' '.$arg2;
}

fdump('do_stuff',array('hello', 'world'));

Returns

  array(3) {
    ["f_success"]=>
    bool(true)
    ["f_time"]=>
    float(0)            //too fast...
    ["f_result"]=>
    string(11) "hello world"
  }
于 2014-01-31T10:46:30.197 に答える
3

Zend Studio には、XDebug または ZendDebugger を使用したプロファイリングのサポートが組み込まれています。コードのプロファイリングを行い、すべての関数にかかった時間を正確に伝えます。これは、ボトルネックがどこにあるかを把握するための優れたツールです。

于 2009-07-29T17:22:53.177 に答える
3

Web コンテキスト外でテストできるものであれば、Unixtimeコマンドを使用します。

于 2009-07-29T13:22:56.640 に答える
1

操作の前後にタイムスタンプや microtime() を保存するなどの基本的なものを使用して、必要な時間を計算できます。これは簡単ですが、あまり正確ではありません。たぶん、より良い解決策はXdebugです。私はそれを使用したことはありませんが、私が見つけることができる最も有名な PHP デバッガー/プロファイラーのようです。

于 2009-07-29T13:30:44.183 に答える