深入了解xhprof性能分析工具

简介: #前言 这篇文章不是教你如何安装使用xhprof进行性能分析。如果想了解如何安装使用xhprof,网络上文章很多,你也可以看我之前写的两篇文章。 [非侵入式监控PHP应用性能监控分析](http://www.bo56.com/%e9%9d%9e%e4%be%b5%e5%85%a5%e5%bc%8f%e7%9b%91%e6%8e%a7php%e5%ba%94%e7%94%a8%e6%80%a7%

前言

这篇文章不是教你如何安装使用xhprof进行性能分析。如果想了解如何安装使用xhprof,网络上文章很多,你也可以看我之前写的两篇文章。
非侵入式监控PHP应用性能监控分析
xhprof gui,让xhprof界面更漂亮,功能更强大

这篇文章主要介绍使用xhprof时的一些常见问题,和xhprof是如何实现性能分析的。

常见问题

多次调用xhprof_enable方法,最后生效的配置是哪个?

当你在一次请求中多次调用xhprof_enable方法,只有第一次调用时进行的设置能生效。在调用xhprof_disable()后,你又可以使用xhprof_enable方法进行设置。

$i = 0;
function good(){
    global $i;
    $i++;
    if ($i < 2) {
        good();
    }
}
function func() {
    good();
}
$start_time = microtime(true);
xhprof_enable(XHPROF_FLAGS_NO_BUILTINS);
xhprof_enable(XHPROF_FLAGS_MEMORY + XHPROF_FLAGS_CPU + XHPROF_FLAGS_NO_BUILTINS);
for ($i = 0; $i < 100; $i++) {
    func();
}
good();
$rst = xhprof_disable();
var_dump($rst);

输出内容为:

array(5) {
  ["good==>good@1"]=>
  array(2) {
    ["ct"]=>
    int(1)
    ["wt"]=>
    int(70)
  }
  ["func==>good"]=>
  array(2) {
    ["ct"]=>
    int(50)
    ["wt"]=>
    int(121)
  }
  ["main()==>func"]=>
  array(2) {
    ["ct"]=>
    int(50)
    ["wt"]=>
    int(135)
  }
  ["main()==>good"]=>
  array(2) {
    ["ct"]=>
    int(1)
    ["wt"]=>
    int(0)
  }
  ["main()"]=>
  array(2) {
    ["ct"]=>
    int(1)
    ["wt"]=>
    int(237)
  }
}

可见,打印的内容,并没有cpu和memory的信息。

输出内容中的ct,wt,cpu,mu, pmu 都代表什么意思

ct 表示 调用的次数
wt 表示 函数方法执行的时间耗时。相当于,在调用前记录一个时间,函数方法调用完毕后,计算时间差。
cpu 表示 函数方法执行消耗的cpu时间。和wt的差别在于,当进程让出cpu使用权后,将不再计算cpu时间。通过调用系统调用getrusage获取进程的占用cpu数据。
mu 表示 函数方法所使用的内存。相当于,在调用前记录一个内存占用,函数方法调用完毕后,计算内存差。调用的是zend_memory_usage获取内存占用情况。
pmu 表示 函数方法所使用的内存峰值。调用的是zend_memory_peak_usage获取内存情况。

输出内容中good==>good@1 是什么意思

==>表示一个调用关系。由于带@,说明是一个递归调用。@后面的数字是递归调用的深度。

如何设置xhprof_enable的参数,减少性能消耗

xhprof_enable提供了三个常量,用于设置你是否需要统计PHP内置函数,都统计那些指标。
三个常量如下:

XHPROF_FLAGS_NO_BUILTINS

设置这个常量后,将不统计PHP内置函数。毕竟PHP的内置函数性能一般都不错。没必要再消耗性能去统计。所以,建议设置。

XHPROF_FLAGS_CPU

设置这个常量后,会统计进程占用CPU时间。由于CPU时间是通过调用系统调用getrusage获取,导致性能比较差。开启这个选项后,大概性能下降一半。因此,如果对cpu耗时不是特别敏感的情况下,建议不要启用这个选项。

XHPROF_FLAGS_MEMORY

设置这个常量后,将会统计内存占用情况。由于获取内存情况,使用的是zend_memory_usage和zend_memory_peak_usage,并不是系统调用。因此,对性能影响不大。如果需要对内存使用情况进行分析的情况下,可以开启。

性能分析原理

如何实现对各个函数方法性能数据记录

目前xhprof会对,加载PHP文件,执行PHP函数方法,和执行eval方法进行性能数据记录。正好,这些在PHP内核中,有对应的函数进行处理。当你调用xhprof_enable方法时,会把默认的方法替换为xhprof的方法。来看看相关代码吧。

static void hp_begin(long level, long xhprof_flags)
{
    if (!hp_globals.enabled)
    {
        int hp_profile_flag = 1;

        hp_globals.enabled = 1;
        hp_globals.xhprof_flags = (uint32) xhprof_flags;

         /* Replace zend_compile with our proxy */
                 /* 处理加载PHP文件 */
                 /* 先把zend引擎默认处理方法保存到_zend_compile_file变量中。*/
        _zend_compile_file = zend_compile_file;
                /* 在把xhprof相对应的方法赋值给zend_compile_file。
                   这样,每次加载PHP文件时,就会执行xhprof相应的方法。*/
        zend_compile_file  = hp_compile_file;

        /* Replace zend_compile_string with our proxy */
                /* 处理eval代码的执行 */
        _zend_compile_string = zend_compile_string;
        zend_compile_string  = hp_compile_string;

        /*init the execute pointer*/
                /* 处理 函数方法的执行 */
        _zend_execute_ex = zend_execute_ex;
        zend_execute_ex  = hp_execute_ex;
              .........
    }
}

/*那我们看下,hp_compile_file方法,又是如何实现的*/
ZEND_DLEXPORT zend_op_array* hp_compile_file(zend_file_handle *file_handle, int type)
{
    const char *filename;
    char *func;
    int len;
    zend_op_array *ret;
    int hp_profile_flag = 1;

    filename = hp_get_base_filename(file_handle->filename);
    len = sizeof("load") - 1 + strlen(filename) + 3;
    func = (char *) emalloc(len);
    snprintf(func, len, "load::%s", filename);
        
        //方法执行前记录当前各项性能如数,如cpu 内存等
    BEGIN_PROFILING(&hp_globals.entries, func, hp_profile_flag);
        //开始zend引擎相应的方法,加载文件
    ret = _zend_compile_file(file_handle, type);
    if (hp_globals.entries)
    {
                //加载文件完毕后,再次记录当前各项性能数据。以便以后计算差值。
        END_PROFILING(&hp_globals.entries, hp_profile_flag);
    }

    efree(func);
    return ret;
}

xhprof在实现的时候,性能方面做了哪些优化

获取时间时,为了性能,使用了汇编来获取时间戳计数器。时间秒 = 时间戳计数器值 / CPU主频。
正是这种实现,导致目前xhprof还只适用于x86架构。此外,因为RDTSC的数据不能在CPU间同步,所以,xhprof会将进程绑定在单个CPU上。
如果SpeedStep技术是打开的,XHProf的基于RDTSC定时器的功能就不能正常工作了。这项技术在某些英特尔处理器上是可用的。[注:苹果台式机和笔记本电脑一般都将SpeedStep技术预设开启。使用XHProf,您需要禁用SpeedStep技术。 ]

inline uint64 cycle_timer()
{
    uint32 __a, __d;
    uint64 val;
    asm volatile("rdtsc" : "=a" (__a), "=d" (__d));
    (val) = ((uint64) __a) | (((uint64) __d) << 32);
    return val;
}
目录
相关文章
|
7月前
|
算法 Unix Linux
【C/C++ 实用工具】性能分析工具一览
【C/C++ 实用工具】性能分析工具一览
332 0
|
7月前
|
数据可视化 关系型数据库 编译器
【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
1085 2
|
7月前
|
Web App开发 JavaScript 前端开发
JavaScript中的性能优化:代码优化技巧与性能分析工具
【4月更文挑战第22天】本文探讨JavaScript性能优化,包括代码优化技巧和性能分析工具。建议避免全局查找、减少DOM操作、使用事件委托、优化循环和异步编程以提升代码效率。推荐使用Chrome DevTools、Lighthouse和jsPerf等工具进行性能检测和优化。持续学习和实践是提升JavaScript应用性能的关键。
|
1月前
|
缓存 监控 Linux
Linux性能分析利器:全面掌握perf工具
【10月更文挑战第18天】 在Linux系统中,性能分析是确保软件运行效率的关键步骤。`perf`工具,作为Linux内核自带的性能分析工具,为开发者提供了强大的性能监控和分析能力。本文将全面介绍`perf`工具的使用,帮助你成为性能优化的高手。
151 1
|
1月前
|
缓存 监控 Linux
掌握Linux性能分析:深入探索perf工具
【10月更文挑战第26天】
65 1
|
2月前
|
Web App开发 监控 JavaScript
一些常用的 Vue 性能分析工具
【10月更文挑战第2天】
144 1
|
3月前
|
SQL 缓存 关系型数据库
MySQL高级篇——性能分析工具
MySQL的慢查询日志,用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long-query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为 10,意思是运行10秒以上(不含10秒)的语句,认为是超出了我们的最大忍耐时间值。它的主要作用是,帮助我们发现那些执行时间特别长的 SOL 查询,并且有针对性地进行优化,从而提高系统的整体效率。当我们的数据库服务器发生阻塞、运行变慢的时候,检查一下慢查询日志,找到那些慢查询,对解决问题很有帮助。
MySQL高级篇——性能分析工具
|
7月前
|
监控 Java 开发者
Java一分钟之-Java性能分析与调优:JProfiler, VisualVM等工具
【5月更文挑战第21天】本文介绍了Java性能优化的两个利器——JProfiler和VisualVM。JProfiler通过CPU Profiler、内存分析器和线程视图帮助解决过度CPU使用、内存泄漏和线程阻塞问题;VisualVM则聚焦于GC行为调整和类加载优化,以减少内存压力和提高应用性能。使用这些工具进行定期性能检查,是提升Java应用效率的关键。
210 0
|
3月前
|
监控 IDE Java
【Java性能调优新工具】JDK 22性能分析器:深度剖析,优化无死角!
【9月更文挑战第9天】JDK 22中的性能分析器为Java应用的性能调优提供了强大的支持。通过深度集成、全面监控、精细化分析和灵活报告生成等核心优势,性能分析器帮助开发者实现了对应用性能的全面掌控和深度优化。在未来的Java开发过程中,我们期待性能分析器能够继续发挥重要作用,为Java应用的性能提升贡献更多力量。
|
4月前
|
存储 缓存 监控
Linux性能分析工具-perf并生成火焰图
Linux性能分析工具-perf并生成火焰图