剖析PHP脚本的最简单方法


289

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

我喜欢在上面显示一些内容,这些内容可以显示所有函数调用的转储以及它们花了多长时间,但我也可以在特定函数周围添加一些内容。

我尝试使用microtime函数进行实验:

$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.999057microtime( TRUE )如@luka 所指出的,您可以用来避免该问题。
JMM 2012年

Answers:


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
APD扩展在php 5.4上已损坏。
天网

作为对user457015的反驳,我能够使其在运行wordpress 3.8.1和PHP 5.3.10的网站上工作,并且看起来工作正常。
Supernovah 2014年

1
@ Supernovah,user457015确实说过PHP 5.4。他没有说它在PHP 5.3上已损坏。
马格努斯2015年

@ user1420752我正在运行5.3.27,它也没有在那里运行。我收到未定义的函数错误。
Fractaly

2
APD的最新版本是2004(!),它不适用于pecl install apdPHP7。当尝试使用进行PHP 5的安装时,它会显示一条错误消息“ config.m4”。看来您必须从源代码安装它,但我还没有尝试过。认真地讲,是否没有一种现代的,更新的基于CLI的PHP概要分析工具,该工具随Homebrew一起安装,需要最少的设置并提供易于理解的输出?

267

我想你想要xdebug。将其安装在服务器上,打开电源,通过kcachegrind(对于linux)或wincachegrind(对于Windows)泵送输出,它将为您显示一些漂亮的图表,详细说明了确切的时间,计数和内存使用情况(但您会为此需要另一个扩展)。

它摇晃,严重:D


6
我发现这比APD解决方案容易实现。但这可能是因为某种原因APD无法在我的系统上正确编译。同样,kcachegrind的图表也和承诺的一样好。
wxs

1
@EvilPuppetMaster,您需要使用--enable-memory-limit编译php或使用更现代的php版本。参见xdebug.org/docs/basic#xdebug_memory_usage
mercutio

52
xdebug + webgrind迅速成为我选择进行快速轻松配置的首选武器。code.google.com/p/webgrind
xkcd150 2010年

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

3
使用XAMPP在Windows上进行操作非常容易。已经为xdebug配置了netbeans。您唯一需要做的就是将php.ini中的xdebug设置更改为xdebug.profiler_output_name =“ cachegrind.out。%t-%s”,否则将不会生成任何输出。需要重新启动apache。
beginner_ 2012年

96

无需扩展,只需使用这两个函数即可进行简单的性能分析。

// 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
连接到数据库
   0.003518
执行查询
   0.000308
检索数据
   0.000009
关闭数据库
   0.000049
完成


37

从离线发布的SO Documentation beta交叉发布我的参考。

使用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直接将表单过帐。

分析输出

写入配置文件缓存后,可以由KCachegrindWebgrind之类的应用程序读取。流行的PHP IDE PHPStorm也可以显示此概要分析数据

KCachegrind

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

  • 执行功能
  • 本身以及包括后续函数调用在内的调用时间
  • 每个函数被调用的次数
  • 通话图
  • 链接到源代码

要找什么

显然,性能调整是针对每个应用程序的用例的。总的来说,寻找:

  • 重复调用您不会希望看到的相同功能。对于处理和查询数据的功能,这可能是应用程序缓存的主要机会。
  • 运行缓慢的功能。应用程序大部分时间都花在哪里?性能调整的最佳回报是将精力集中在应用程序上耗时最多的部分上。

注意:Xdebug,尤其是它的概要分析功能,占用大量资源,并降低了PHP执行速度。建议不要在生产服务器环境中运行它们。


3
添加到分析配置文件缓存的工具列表中:PhpStorm还提供了一个预览配置文件缓存的工具
peterchaula

1
@peter我忘了PHPStorm具有该功能。我已经添加了指向文档的链接。谢谢!
Matt S

有什么方法可以直接在服务器上获取文本(非GUI)报告吗?
Alexander Shcheblikin

1
@Mark,您能将此标记为答案吗?当前的答案已经过时了,即使发布了很多年也没有用过。
Mawg说恢复莫妮卡

24

如果减去微时间会带来负面结果,请尝试使用带有参数truemicrotime(true))的函数。使用true,该函数返回浮点数而不是字符串(如不带参数调用时一样)。


24

老实说,我将争论使用NewRelic进行性能分析是最好的。

这是一个PHP扩展,似乎根本不会减慢运行时间,并且它们会为您进行监视,从而实现良好的向下钻取。在昂贵的版本中,它们允许大量下钻(但我们无法负担其定价模型)。

尽管如此,即使有了免费/标准计划,大多数悬而未决的地方也很明显而且很简单。我也喜欢它,它也可以为您提供有关数据库交互的想法。

分析时界面之一的屏幕截图


16
当然,New Relic看起来很有希望。但是,他们的隐私权政策中 “披露您的应用程序数据”部分立即使我反感。恕我直言,与第三方共享专有源代码的片段有点过多。
Cengiz 2014年

8
此处并没有进行防御,但看起来“应用程序数据”只是性能信息和系统配置信息,而不是您的应用程序源代码。
戴维·希尔兹

冷杉,我的新遗物显示我的“ WebTransaction”显示为99%的时间,并且没有“ ApplicationTraces”的专业帐户
Karthik T 2014年

1
尝试在以下位置进行注册:newrelic.com/rackspace <应该免费给您“标准”
zeroasterisk,2014年

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和更高版本的PEAR软件包...
dland

1
Facebook通过php 5.5创建了一个带有支持的叉子github.com/facebook/xhprof
borkencode 2013年

也可以检查此fork并提出一些其他调整:github.com/preinheimer/xhprof
Fedir RYKHTIK 2013年

xhprof.io提供了使用XHProf收集的数据的GUI,以及将数据存储在数据库中以进行历史分析的功能。我是后者实现的作者。
Gajus 2014年

10

我喜欢使用phpDebug进行性能分析。 http://phpdebug.sourceforge.net/www/index.html

它输出所有使用的SQL以及所有包含的文件的所有时间/内存使用情况。显然,它最适合抽象的代码。

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



6

对于基准测试,就像您的示例一样,我使用pear Benchmark软件包。您设置用于测量的标记。该课程还提供了一些演示帮助器,或者您可以根据需要处理数据。

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


3

XDebug不稳定,并且不适用于特定的php版本。例如,在某些服务器上,我仍然运行php-5.1.6,这是RedHat RHEL5附带的(并且btw仍会接收所有重要问题的更新),而最近的XDebug甚至没有使用此php进行编译。所以最后我切换到DBG调试器。 它的php基准测试为功能,方法,模块甚至行提供了计时。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.