分析PHP脚本的最简单方法

分析PHP脚本最简单的方法是什么?

我喜欢在上面添加一些东西,告诉我所有函数调用的转储以及它们花了多长时间,但我也可以在特定的函数周围放一些东西。

我尝试了microtime函数:

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


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

但这有时会给我带来负面结果。另外,在我的代码中散布这些代码会带来很多麻烦。

207813 次浏览
我喜欢使用phpDebug进行剖析。 http://phpdebug.sourceforge.net/www/index.html < / p >

它输出使用的任何SQL以及所有包含的文件的所有时间/内存使用情况。显然,它在抽象的代码上工作得最好。

对于函数和类分析,我只使用microtime() + get_memory_usage() + get_peak_memory_usage()

我认为你需要xdebug。在服务器上安装它,打开它,通过kcachegrind (linux)或wincachegrind (windows)输出,它会向你展示一些漂亮的图表,详细说明准确的计时,计数和内存使用(但你需要另一个扩展)。

这真的很震撼:D

PECL adp扩展的用法如下:

<?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年,扩展不再维护,并有各种兼容性问题(见评论)。

对于基准测试,就像在你的例子中,我使用梨基准包。你设置标记来测量。该类还提供了一些表示帮助程序,或者您可以根据自己的需要处理数据。

我实际上用__destruct方法将它包装在另一个类中。当脚本退出时,输出将通过log4php记录到syslog,因此我有很多性能数据可以使用。

PECL XHPROF看起来也很有趣。它有用于查看报告的可点击的HTML界面和非常简单的文档。不过我还没有测试过。

如果减去microtimes得到的结果是负数,请尝试使用带有参数true (microtime(true))的函数。使用true,函数返回一个浮点数而不是字符串(如果调用时不带参数,则会这样做)。

XDebug并不稳定,而且并不总是适用于特定的php版本。例如,在一些服务器上,我仍然运行php-5.1.6,这是RedHat RHEL5附带的(顺便说一下,所有重要问题仍然会收到更新),而且最近的XDebug甚至不使用这个php编译。所以我最终切换到DBG调试器 它的php基准测试为函数、方法、模块甚至行提供计时

老实说,我认为使用NewRelic进行分析是最好的。

这是一个PHP扩展,似乎并不会减慢运行时,他们为你做监控,允许体面的钻。在昂贵的版本中,他们允许重钻(但我们负担不起他们的定价模式)。

尽管如此,即使使用免费/标准计划,大多数容易实现的目标也是显而易见和简单的。我也喜欢它可以给你一个关于DB交互的想法。

分析时其中一个接口的截图

不需要扩展,只需使用这两个函数进行简单的概要分析。

// 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 < br > < b >执行查询
,, 0.000308 < br > < b >检索数据
,, 0.000009 < br > < b >关闭数据库
,, 0.000049 < br > < b > < br >

我会大胆地给黑焰一个尝试。

这里是我用puphpet把这个virtualBox放在一起,来测试与BlackFire相连接的不同php框架,如果需要,请随意分叉和/或分发:)

https://github.com/webit4me/PHPFrameworks

可怜人的侧写,不需要扩展。支持嵌套配置文件和总百分比:

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
]
]

交叉张贴我的参考从SO文档测试版下线。

使用XDebug进行分析

PHP的一个名为Xdebug的扩展可以帮助进行分析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"

接下来,使用web客户端向你想要分析的应用程序的URL发出请求。

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

在处理页面时,它将写入名称类似于的文件

/tmp/cachegrind.out.12345

默认情况下,文件名中的数字是写入它的进程id。这可以通过xdebug.profiler_output_name设置进行配置。

注意,它将为执行的每个PHP请求/进程编写一个文件。因此,例如,如果您希望分析一个表单帖子,那么将为GET请求编写一个概要文件来显示HTML表单。XDEBUG_PROFILE参数需要传递到后续的POST请求中,以分析处理表单的第二个请求。因此,在分析表单时,有时使用curl直接POST表单会更容易一些。

分析输出

一旦写入配置文件缓存,就可以由诸如KCachegrindWebgrind这样的应用程序读取。PHPStorm,一个流行的PHP IDE,也可以显示此分析数据

KCachegrind

例如,KCachegrind将显示以下信息:

  • 函数执行
  • 调用时间,包括本身和后续函数调用
  • 每个函数被调用的次数
  • 调用图
  • 源代码链接

注意什么

显然,性能调优非常特定于每个应用程序的用例。一般来说,最好是寻找:

  • 重复调用您不希望看到的同一个函数。对于处理和查询数据的函数,这些可能是应用程序缓存的主要机会。
  • 缓慢运行功能。应用程序将大部分时间花费在哪里?性能调优的最佳回报是关注应用程序中消耗时间最多的部分。

请注意: Xdebug,特别是它的分析特性,是非常资源密集型和降低PHP执行速度。建议不要在生产服务器环境中运行这些命令。

你们都应该检查一下这个新的php分析器。

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

它重新定义了php分析器收集和显示结果的方式。 PHP-SPX不只是输出特定函数调用的总数和执行它所花费的总时间,而是以一种完全可读的方式显示了请求执行的整个时间轴。下图为其提供的GUI界面

enter image description here