xdebug + kcachegrind实现php程序的性能分析

http://kcachegrind.sourceforge.net/html/Download.html

工作了一两年的 PHPer 大概都多多少少知道一些性能分析的工具,比如 Xdebug、xhprof、New Relic 、OneAPM。使用基于 Xdebug 进行 PHP 的性能分析,对于本地开发环境来说是够用了,但如果是线上环境的话,xdebug 消耗较大,配置也不够灵活。相比 Xdebug ,xhprof 性能消耗较小,但是 xhprof 注入代码后我们还需要实现保存 xhprof 数据以及展示数据的 UI,听起来似乎又是一大堆工作。

 

我们在做php应用的时候(就是气氛很轻松那种, 要是任务压力大, 上头又催得急就别管它死活了...人活着是第一), 有时候希望知道程序执行的效率. 一般情况下自然是用php自带的time函数来分析运行时间, 不是太长的话就算过了...
但在考虑相对严肃的环境里, 我们就需要额外的工具去分析程序执行的效率.

当然php已经有了这种模块, 这就是xdebug. 如何安装等等, 我们不再描述.
额外的配置可以看这个:

[root@localhost  ~]# cat /etc/php.d/xdebug.ini
; Enable xdebug extension module
zend_extension=/usr/lib/php/modules/xdebug.so

; added by yarco
xdebug.auto_trace=On
xdebug.collect_params=On
xdebug.collect_return=On
xdebug.collect_vars=On
xdebug.profiler_enable=On
xdebug.profiler_output_dir=/tmp/xdebug
xdebug.trace_output_dir=/tmp/xdebug


这是我的.
这样在运行web程序的时候, 通常会产生类似的额外的性能分析文件. 比如:

[root@localhost  ~]# ls /tmp/xdebug
cachegrind.out.6184 cachegrind.out.6876 cachegrind.out.6880         trace.2043925204.037608.xt
cachegrind.out.6705 cachegrind.out.6877 cachegrind.out.6881         trace.2043925204.03b8a2.xt
cachegrind.out.6874 cachegrind.out.6878 cachegrind.out.6882         trace.2043925204.xt
cachegrind.out.6875 cachegrind.out.6879 trace.2043925204.0195df.xt

虽然很难从这些文件名里看出到底执行的是哪个文件, 不过一般都是固定的.
当然直接看这些文件是件很傻的事情, 我们有性能分析工具:
[root@localhost  ~]# head /tmp/xdebug/cachegrind.out.6184
version: 0.9.6
cmd: /home/yarco/Public/workspace/代码/coto/index.php
part: 1

events: Time

fl=php:internal
fn=php::dirname
15 2

在linux下就叫Kcachegrind(windows下应该也有, 自己找找可以找到).
用该工具打开那个文件, 产生的效果如下:
13110909_ZySa.jpg
这是我自己的php框架运行的结果.(你的可能略有不同).

比较重要的两个字段是self和called.
前一个表示该过程自身所消耗的时间百分比;
后一个表示被调用次数.

举个例子, 在我的框架里, 我写了一个__autoload的函数, 那么当自动调用发生的时候, 就会执行...但假如框架里的确会用到某个类, 那么就可以直接require/include进来, 那么就不会去调用autoload...这样就会使得autoload被调用的次数减少...毕竟动态载入肯定没静态载入运行速度快, 从而达到提高性能的目的.

更新:
在该性能分析器里我们发现函数cotorequire被调用了15次, 并且耗时比重为24.69.
我们觉得相对来说有优化的需要和可能性. 我们来看下cotorequire是如何写的.

上下文diff形式, 比较下前后改进的差别:

function cotorequire($modulename, $classname)
{
!       $files[] = sprintf("%s%s/%s.php", COTO_PATH, strtolower($modulename), $classname);
!       $files[] = sprintf("%s/usr/%s/%s.php", APP_PATH, strtolower($modulename), $classname);
!       foreach($files as $file)
{
!               if (is_readable($file))
!               {
!                       require_once $file;
!               }
}
}

--- 85,101 ----
*/
function cotorequire($modulename, $classname)
{
!       $file = sprintf("%s%s/%s.php", COTO_PATH, strtolower($modulename), $classname);
!       if (is_readable($file))
{
!               require_once $file;
!               return;
!       }
!
!       $file = sprintf("%s/usr/%s/%s.php", APP_PATH, strtolower($modulename), $classname);
!       if (is_readable($file))
!       {
!               require_once $file;
}
}

1) 我们用单独的变量替代了数组.(该函数是根据类名去查找系统和用户目录下的某个文件然后包含之, 所以不太可能增加更多的path)
2) 在系统找到该文件后, 立刻返回

之前:
Incl. 33.05 Self 24.69 Called 15
现在:
incl. 22.80 Self 14.64 Called 15

优化的效果还是很明显的

update: 2010-08-20
mac下可以使用maccallgrind: www.maccallgrind.com/get
(不过目前似乎处于不断完善中)

转载于:https://my.oschina.net/mickelfeng/blog/279031

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值