PHPスクリプトをプロファイルする最も簡単な方法


289

PHPスクリプトをプロファイリングする最も簡単な方法は何ですか?

私は、すべての関数呼び出しのダンプとそれらにかかった時間を示す何かに取り組むのが大好きですが、特定の関数の周りに何かを置いても大丈夫です。

マイクロタイム関数を試してみました:

$then = microtime();
myFunc();
$now = microtime();

echo sprintf("Elapsed:  %f", $now-$then);

しかし、それは時々私に否定的な結果を与えます。加えて、それを私のコード全体にまき散らすことは非常に困難です。


7
ねえマーク、否定的なコメントを解決するのに役立つこのコメントをチェックしてください:ro.php.net/manual/en/function.microtime.php#99524
Mina

16
@Midianeによってリンクされたコメントは意味がありません。それがコメンターの問題を解決するように思われた場合、それは偶然だったに違いありません。だけを使用microtime()すると"0.00154800 1342892546" - "0.99905700 1342892545"、次のような式が評価されることがあります0.001548 - 0.999057。@lukaが指摘microtime( TRUE )するように、この問題を回避するために使用できます。
JMM 2012

回答:


104

PECL APDを次のように拡張子が使用されます。

<?php
apd_set_pprof_trace();

//rest of the script
?>

その後、を使用して、生成されたファイルを解析しますpprofp

出力例:

Trace for /home/dan/testapd.php
Total Elapsed Time = 0.00
Total System Time  = 0.00
Total User Time    = 0.00


Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
100.0 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0000   0.0009            0 main
56.9 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0005   0.0005            0 apd_set_pprof_trace
28.0 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 preg_replace
14.3 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 str_replace

警告:APDの最新リリースは2004年日付であり、拡張機能はもはや維持されておらず、さまざまな互換性の問題があります(コメントを参照)。


19
PHP 5.4でAPD拡張機能が壊れています。
スカイネット

user457015に返答して、wordpress 3.8.1とPHP 5.3.10を実行しているWebサイトで動作させることができましたが、問題なく動作するようでした。
超新星2014年

1
@ Supernovah、user457015はPHP 5.4と言っていました。彼はそれがPHP 5.3で壊れているとは言いませんでした。
magnus 2015年

@ user1420752 5.3.27を実行していますが、そこでも実行されていません。未定義の関数エラーが発生します。
Fractaly 2016

2
APDの最新リリースは2004年(!)からです。PHP7では動作しません。PHP5をでインストールしようとするとpecl install apd、「config.m4」に関するエラーメッセージが表示されます。ソースからインストールする必要があるようですが、私はまだ試していません。真剣に、Homebrewと共にインストールされ、最小限の設定で簡単に人間が読める出力を提供する、PHP用の最新の更新されたCLIベースのプロファイリングツールはありませんか?
フォースリン

267

xdebugが欲しいと思います。サーバーにインストールし、オンにして、出力をkcachegrind(Linuxの場合)またはwincachegrind(Windowsの場合)に送ります。正​​確なタイミング、カウント、およびメモリ使用量の詳細を示すいくつかの美しいグラフが表示されます(ただし、そのために別の拡張が必要です)。

それは揺れる、真剣:D


6
これは、APDソリューションよりも実装がはるかに簡単であることがわかりました。しかし、それはおそらく、何らかの理由でAPDが私のシステムで適切にコンパイルされなかったためです。また、kcachegrindのグラフは約束されたとおりにきれいでした。
wxs 2008

1
@EvilPuppetMaster、-enable-memory-limitでphpをコンパイルするか、より最新のphpバージョンを使用する必要があります。xdebug.org/docs/basic#xdebug_memory_usage
mercutio

52
xdebug + webgrindは、すばやく簡単にプロファイリングを行うための私の武器になりました。code.google.com/p/webgrind
xkcd150

6
xdebug + xdebug_start_trace()+ xdebug_stop_trace()= win
quano

3
これは、XAMPPを使用してWindowsで作業するのが非常に簡単でした。xdebug用に構成されたnetbeansはすでにありました。行う必要があるのは、php.iniのxdebug設定をxdebug.profiler_output_name = "cachegrind.out。%t-%s"に変更することだけです。そうしないと、出力は生成されません。Apacheの再起動が必要です。
beginner_

97

拡張機能は必要ありません。単純なプロファイリングにはこれら2つの関数を使用してください。

// Call this at each point of interest, passing a descriptive string
function prof_flag($str)
{
    global $prof_timing, $prof_names;
    $prof_timing[] = microtime(true);
    $prof_names[] = $str;
}

// Call this when you're done and want to see the results
function prof_print()
{
    global $prof_timing, $prof_names;
    $size = count($prof_timing);
    for($i=0;$i<$size - 1; $i++)
    {
        echo "<b>{$prof_names[$i]}</b><br>";
        echo sprintf("&nbsp;&nbsp;&nbsp;%f<br>", $prof_timing[$i+1]-$prof_timing[$i]);
    }
    echo "<b>{$prof_names[$size-1]}</b><br>";
}

以下に例を示します。各チェックポイントに説明を付けてprof_flag()を呼び出し、最後にprof_print()を呼び出します。

prof_flag("Start");

   include '../lib/database.php';
   include '../lib/helper_func.php';

prof_flag("Connect to DB");

   connect_to_db();

prof_flag("Perform query");

   // Get all the data

   $select_query = "SELECT * FROM data_table";
   $result = mysql_query($select_query);

prof_flag("Retrieve data");

   $rows = array();
   $found_data=false;
   while($r = mysql_fetch_assoc($result))
   {
       $found_data=true;
       $rows[] = $r;
   }

prof_flag("Close DB");

   mysql_close();   //close database connection

prof_flag("Done");
prof_print();

出力は次のようになります。

開始
   0.004303
DBに接続
   0.003518
クエリを実行
   0.000308
データを取得
   0.000009
DBを閉じる
   0.000049
完了


37

オフラインになるSOドキュメントのベータ版から私の参照をクロスポストします。

XDebugによるプロファイリング

Xdebugと呼ばれるPHPの拡張機能は、PHPアプリケーションのプロファイリングやランタイムデバッグを支援するために利用できます。プロファイラーを実行すると、出力は「cachegrind」と呼ばれるバイナリ形式でファイルに書き込まれます。これらのファイルを分析するためのアプリケーションが各プラットフォームで利用可能です。 このプロファイリングを実行するためにアプリケーションコードを変更する必要はありません。

プロファイリングを有効にするには、拡張機能をインストールし、php.ini設定を調整します。一部のLinuxディストリビューションには、標準パッケージ(Ubuntuのphp-xdebugパッケージなど)が付属しています。この例では、要求パラメーターに基づいてオプションでプロファイルを実行します。これにより、設定を静的に保ち、必要な場合にのみプロファイラーをオンにすることができます。

# php.ini settings
# Set to 1 to turn it on for every request
xdebug.profiler_enable = 0
# Let's use a GET/POST parameter to turn on the profiler
xdebug.profiler_enable_trigger = 1
# The GET/POST value we will pass; empty for any value
xdebug.profiler_enable_trigger_value = ""
# Output cachegrind files to /tmp so our system cleans them up later
xdebug.profiler_output_dir = "/tmp"
xdebug.profiler_output_name = "cachegrind.out.%p"

次に、ウェブクライアントを使用して、プロファイリングするアプリケーションのURLにリクエストを送信します。

http://example.com/article/1?XDEBUG_PROFILE=1

ページが処理されると、次のような名前のファイルに書き込まれます

/tmp/cachegrind.out.12345

デフォルトでは、ファイル名の番号はそれを書き込んだプロセスIDです。これは設定で構成可能xdebug.profiler_output_nameです。

実行されるPHPリクエスト/プロセスごとに1つのファイルを書き込むことに注意してください。したがって、たとえば、フォームの投稿を分析したい場合、GETリクエストがHTMLフォームを表示するためのプロファイルが1つ書き込まれます。XDEBUG_PROFILEパラメータを後続のPOSTリクエストに渡して、フォームを処理する2番目のリクエストを分析する必要があります。したがって、プロファイリングの際に、curlを実行してフォームを直接POSTする方が簡単な場合があります。

出力の分析

いったん書き込まれると、プロファイルキャッシュはKCachegrindWebgrindなどのアプリケーションで読み取ることができます。人気のあるPHP IDEであるPHPStormも、このプロファイリングデータを表示できます

KCachegrind

たとえば、KCachegrindは次のような情報を表示します。

  • 実行される機能
  • それ自体と後続の関数呼び出しを含む呼び出し時間
  • 各関数が呼び出された回数
  • コールグラフ
  • ソースコードへのリンク

何を探すべきか

明らかに、パフォーマンスの調整は、各アプリケーションの使用例に非常に固有です。一般的には、次のことを探すのが良いでしょう。

  • 予期しない同じ関数への繰り返しの呼び出し。データを処理および照会する関数の場合、これらはアプリケーションがキャッシュする主要な機会になる可能性があります。
  • 実行が遅い関数。アプリケーションはほとんどの時間をどこで費やしていますか?パフォーマンスチューニングで最も効果的なのは、アプリケーションの中で最も時間を消費する部分に焦点を当てることです。

:Xdebug、特にそのプロファイリング機能は非常に多くのリソースを消費し、PHPの実行を遅くします。これらを運用サーバー環境で実行しないことをお勧めします。


3
プロファイルキャッシュを解析するためのツールのリストに追加する:PhpStormには、プロファイルキャッシュをプレビューするためのツールもあります
peterchaula

1
@peter私はPHPStormにその機能があることを忘れました。ドキュメントへのリンクを追加しました。ありがとう!
マットS

サーバー上でテキスト(非GUI)レポートを直接取得する方法はありますか?
Alexander Shcheblikin

1
@Markは、これを回答としてマークしてください。現在の答えは投稿されても時代遅れであり、長年にわたって機能していません。これは機能し、私にはこれ以上の方法はありません。
モーグはモニカを

24

マイクロタイムを減算すると否定的な結果が得られる場合は、引数truemicrotime(true))を指定して関数を使用してみてください。を使用するtrueと、関数は文字列ではなく浮動小数点数を返します(引数なしで呼び出された場合と同様)。


24

正直なところ、プロファイリングにNewRelicを使用するのが最善だと主張します。

これはPHPの拡張機能であり、ランタイムをまったく低下させないようであり、モニタリングを実行して、適切なドリルダウンを可能にします。高価なバージョンでは、詳細なドリルダウンが可能です(ただし、価格モデルを購入する余裕はありません)。

それでも、無料/標準プランを使用しても、ほとんどの低ぶら下げ果物がどこにあるかは明白で簡単です。また、DBの相互作用についても説明できることも気に入っています。

プロファイリング時のインターフェースの1つのスクリーンショット


16
New Relicは確かに有望に見えます。しかし、彼らのプライバシーポリシーの「あなたのアプリケーションデータの開示」の部分はすぐに私を弾きました。Imho、プロプライエタリなソースコードの一部をサードパーティと共有するのは少しやりすぎです。
Cengiz Can 2014

8
ここで彼らの防御に跳躍しているわけではありませんが、「アプリケーションデータ」はパフォーマンス情報とシステム構成情報であり、アプリケーションのソースコードではないようです。
David Shields

私の新しい遺物が私の「WebTransaction」を99%の時間として表示していて、「ApplicationTraces」のプロアカウントを持っていない
Karthik T 14年

1
newrelic.com/rackspace < でサインアップしてみてください。無料で「標準」が提供されます
zeroasterisk

15

貧乏人のプロファイリング、拡張は必要ありません。ネストされたプロファイルと合計のパーセントをサポートします:

function p_open($flag) {
    global $p_times;
    if (null === $p_times)
        $p_times = [];
    if (! array_key_exists($flag, $p_times))
        $p_times[$flag] = [ 'total' => 0, 'open' => 0 ];
    $p_times[$flag]['open'] = microtime(true);
}

function p_close($flag)
{
    global $p_times;
    if (isset($p_times[$flag]['open'])) {
        $p_times[$flag]['total'] += (microtime(true) - $p_times[$flag]['open']);
        unset($p_times[$flag]['open']);
    }
}

function p_dump()
{
    global $p_times;
    $dump = [];
    $sum  = 0;
    foreach ($p_times as $flag => $info) {
        $dump[$flag]['elapsed'] = $info['total'];
        $sum += $info['total'];
    }
    foreach ($dump as $flag => $info) {
        $dump[$flag]['percent'] = $dump[$flag]['elapsed']/$sum;
    }
    return $dump;
}

例:

<?php

p_open('foo');
sleep(1);
p_open('bar');
sleep(2);
p_open('baz');
sleep(3);
p_close('baz');
sleep(2);
p_close('bar');
sleep(1);
p_close('foo');

var_dump(p_dump());

収量:

array:3 [
  "foo" => array:2 [
    "elapsed" => 9.000766992569
    "percent" => 0.4736904954747
  ]
  "bar" => array:2 [
    "elapsed" => 7.0004580020905
    "percent" => 0.36841864946596
  ]
  "baz" => array:2 [
    "elapsed" => 3.0001420974731
    "percent" => 0.15789085505934
  ]
]

13

PECL XHPROFも魅力的です。それは持っているクリッカブルHTMLインターフェイスレポートの表示と非常に簡単のためのマニュアルを参照して。私はまだそれをテストする必要があります。


それはあまり愛されていないようです。2009年の最終更新、
5.3、5.4

1
Facebookはphp 5.5 github.com/facebook/xhprof
borkencode

いくつかの追加調整を提案するこのフォークも確認してください:github.com/preinheimer/xhprof
Fedir RYKHTIK

xhprof.ioは、XHProfを使用して収集されたデータのGUIと、履歴分析のためにデータベースにデータを格納する機能を提供します。私は後者の実装の作者です。
Gajus 14

10

プロファイリングにphpDebugを使用するのが好きです。 http://phpdebug.sourceforge.net/www/index.html

使用されているSQLのすべての時間/メモリ使用量と、含まれているすべてのファイルを出力します。明らかに、それは抽象化されたコードで最もよく機能します。

関数やクラスのために、私はちょうど使用しますプロファイリングmicrotime()+ get_memory_usage()+ get_peak_memory_usage()



6

ベンチマークには、例のように、pearベンチマークパッケージを使用します。測定用のマーカーを設定します。このクラスは、いくつかのプレゼンテーションヘルパーも提供します。または、必要に応じてデータを処理できます。

実際には、__ destructメソッドを使用して別のクラスにラップしています。スクリプトが終了すると、出力はlog4phpを介してsyslogに記録されるため、多くのパフォーマンスデータを取得できます。


3

XDebugは安定しておらず、特定のPHPバージョンで常に使用できるとは限りません。たとえば、一部のサーバーでは私はまだphp-5.1.6を実行しています-RedHat RHEL5に付属しているものであり(btwはすべての重要な問題の更新をまだ受信しています)、最近のXDebugはこのphpでコンパイルできません。そのため、DBGデバッガーに切り替えました。 そのphpベンチマークは、関数、メソッド、モジュール、さらにはラインのタイミングを提供します。


2

あなたは間違いなくこの新しいphpプロファイラーをチェックする必要があります。

https://github.com/NoiseByNorthwest/php-spx

PHPプロファイラーが結果を収集して表示する方法を再定義します。特定の関数呼び出しの総数とその実行に費やされた合計時間だけを出力する代わりに、PHP-SPXは完全に読み取り可能な方法で要求実行の全体のタイムラインを示します。以下はそれが提供するGUIの画面です。

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.