PHP性能查看神器xhprof的安装和使用

在文章的开始我们先说说Facebook的架构,Facebook的官方语言是PHP,但是PHP的局限性太大,WEB之外的应用用PHP来写就特别别扭。但Facebook早期的架构就是PHP写的,想全部改成Java或者Python不太实际。所以Facebook的工程师就自己重写编译器用来解析PHP。不难看出国外和国内互联网公司在技术上还是差很大的,像谷歌随便就整个Go语言,Facebook随便就能弄个编译器出来……之后Facebook也一直用PHP作为官方语言,并且开源了大量优质并且实用的工具。XHProf就是其中一个。

XHProf是一个分层PHP性能分析工具。它报告函数级别的请求次数和各种指标,包括阻塞时间,CPU时间和内存使用情况。一个函数的开销,可细分成调用者和被调用者的开销,XHProf数据收集阶段,它记录调用次数的追踪和包容性的指标弧在动态callgraph的一个程序。它独有的数据计算的报告/后处理阶段。在数据收集时,XHProfd通过检测循环来处理递归的函数调用,并通过给递归调用中每个深度的调用一个有用的命名来避开死循环。XHProf分析报告有助于理解被执行的代码的结构,它有一个简单的HTML的用户界面(PHP写成的)。基于浏览器的性能分析用户界面能更容易查看,或是与同行们分享成果。也能绘制调用关系图。

一.下载

Linux下安装就不说了(教程一大把)略过。介绍下Windows下如何安卓XHProf。
下载地址:http://windows.php.net/downloads/pecl/releases/xhprof/0.10.6/
Windows下一般下载ts(Thread Safety)版本,不确定的看下phpinfo中的Thread Safety参数是否是enabled。

二.安装

将下载到的文件解压,并将XHProf.dll文件放到php的ext目录下。然后修改php.ini文件,加入下面配置信息

1
2
3
4
5
6
7
[xhprof]
;dll file name
extension=php\_xhprof.dll
; directory used by default implementation of the iXHProfRuns
; interface (namely, the XHProfRuns\_Default class) for storing
; XHProf runs.
xhprof.output\_dir="d:/xampp/locale"

文件名和路径根据实际情况去填写。之后重启apache。

三.调用

先下载 http://pan.baidu.com/s/1eQnen8u 文件,然后将该项目文件解压到服务器根目录。之后在要运行的项目中加入如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// cpu:XHPROF\_FLAGS\_CPU 内存:XHPROF\_FLAGS\_MEMORY  
// 如果两个一起:XHPROF\_FLAGS\_CPU + XHPROF\_FLAGS\_MEMORY
xhprof\_enable(XHPROF\_FLAGS\_CPU + XHPROF\_FLAGS\_MEMORY);

// 要测试的php代码
echo "代码写在这里,其他不用管";
$data = xhprof\_disable(); //返回运行数据

// xhprof\_lib在下载的包里存在这个目录,记得将目录包含到运行的php代码中
include\_once "xhprof\_lib/utils/xhprof\_lib.php";
include\_once "xhprof\_lib/utils/xhprof\_runs.php";
$objXhprofRun = new XHProfRuns\_Default();
$run\_id = $objXhprofRun->save\_run($data, "xhprof\_foo");
echo "[XHProf view](http://blog.it2048.cn/%3Cspan%20style='color:#ff0000;'>http://127.0.0.1/debug/xhprof_html/index.php?run=' . $run_id . '&source=xhprof_foo)";

代码中标红的注意路径写对就行了。之后运行代码就能看到效果。如下

Calls:函数的调用次数
Incl. Wall Time (microsec) :包含内部函数花费的时间,单位微秒
Excl. Wall Time (microsec):不包含内部函数花费的时间,单位微秒
及所占百分比(%)

注:Incl.:为 Including 包含的简写
Excl.:为 Excluding 不包含的简写
Wall Time:意为挂钟时间即任务花费的时间

main():一个虚构的函数,程序根节点
bar@2:递归调用 2 次

Incl. CPU (microsecs):包含内部函数 CPU 花费的时间,单位微秒
Excl. CPU (microsec):不包含内部函数 CPU 花费的时间,单位微秒
Incl. MemUse (bytes):包含内部函数所占内存,单位字节
Excl. MemUse (bytes):不包含内部函数所占内存,单位字节
Incl. PeakMemUse (bytes):包含内部函数所占内存峰值,单位字节
Excl. PeakMemUse (bytes):不包含内部函数所占内存峰值,单位字节
及所占百分比(%)

可以认为共三种情况:

  1. 包括内部函数
  2. 不包括内部函数或者说函数本身
  3. 所占总数(时间或内存使用)的百分比