如何基准测试PHP脚本的效率


131

我想知道什么是基准测试我的PHP脚本的最佳方法。cron作业,网页或Web服务无关紧要。

我知道我可以使用microtime,但这真的给了我PHP脚本的实时性吗?

我想测试和比较PHP中执行相同功能的不同函数。例如,preg_matchvs strposdomdocumentvs preg_match或preg_replace vs str_replace`

网页示例:

<?php
// login.php

$start_time = microtime(TRUE);

session_start(); 
// do all my logic etc...

$end_time = microtime(TRUE);

echo $end_time - $start_time;

这将输出:0.0146126717(一直在变化-但这是我得到的最后一个)。这意味着执行PHP脚本大约需要0.015。

有没有更好的办法?



4
0.015秒。眼睛的平均眨眼速度为0.3秒。您是否真的需要提高速度,请问为什么?

4
@ben是一个例子,我的页面加载时间为0.8秒,每小时访客超过5万,我需要确保页面加载速度快
eric

8
@MarcB亚马逊显然进行了测试,发现100ms的延迟导致销售下降1%。对于像亚马逊这样的大型网站而言,这可能是数十亿美元。highscalability.com/...
ceejayoz

1
@ceejayoz是的,如果您是亚马逊人,那将是一个大问题,但如果您不是这样,则请谨慎行事,以追求疯狂的页面加载时间。亚马逊做了作业,因此可以轻松证明花费X工时来弥补Y的销售下降。这里的课是你自己做功课!
James Butler

Answers:


122

如果您确实想对真实世界的代码进行基准测试,请使用XdebugXHProf之类的工具。

Xdebug非常适合在开发/暂存中工作,并且XHProf是用于生产的出色工具,并且可以在此处安全运行(只要您阅读了说明)。任何单个页面加载的结果都不会像看到服务器在执行一百万其他事情并且资源变得稀缺时锤打代码的效果那样重要。这就提出了另一个问题:您是否正在瓶颈CPU?内存?输入/输出?

您还需要关注的不仅仅是脚本中运行的代码,而是如何提供脚本/页面。您正在使用什么Web服务器?举例来说,我可以使nginx + PHP-FPM认真执行mod_php + Apache,这反过来会因使用良好的CDN提供静态内容而被淘汰。

接下来要考虑的是您要优化的内容?

  • 页面在用户浏览器中呈现的速度是否是第一要务?
  • 目标是尽快以最少的CPU消耗将对服务器的每个请求扔回去吗?

前者可以通过gzip压缩发送到浏览器的所有资源的方式来获得帮助,但是这样做(在某些情况下)可能会使您进一步远离实现后者。

希望以上所有内容可以帮助表明,精心隔离的“实验室”测试不会反映您在生产中会遇到的变量和问题,并且您必须确定您的高级目标是什么,然后才能达到目标,在前往微观/过早优化路线前往地狱之前


6
如果这确实回答了您的问题,我认为您的问题措词不正确(或者我读错了)。根据您的问题,听起来您想隔离使用PHP进行同一操作的不同方法,并确定哪种方法最快。但是,根据您接受并给予的赏金,似乎您对整个Web堆栈的负载测试更感兴趣-完全不同。
亚历克峡谷

Xdebug不支持Ioncube编码的脚本。您如何基准测试这些脚本?
2013年

@BigSack您有点自己,我从来没有尝试过对那些被混淆的内容进行概要分析。我首先要使用XHProf拍摄照片,因为那相对容易运行。您可能会发现IonCube完全干扰了任何非userland Profiler。
詹姆斯·巴特勒

Nginx vs Apache声明有点偏颇。最被忽略的原因是AllowOveride导致Apache在每次请求时遍历.htaccess文件的整个目录。仅此一项就使Apache脱离了自己的方式。
B00MER


30

您将要研究Xdebug,更具体地说是Xdebug的分析功能

基本上,您启用了探查器,并且每次加载网页时,它都会创建一个可被WinCacheGrindKCacheGrind读取的cachegrind文件。

Xdebug的配置可能有些棘手,因此这是我的相关部分php.ini供参考:

[XDebug]
zend_extension = h:\xampp\php\ext\php_xdebug-2.1.1-5.3-vc6.dll
xdebug.remote_enable=true
xdebug.profiler_enable_trigger=1
xdebug.profiler_output_dir=h:\xampp\cachegrind
xdebug.profiler_output_name=callgrind.%t_%R.out

这是WinCacheGrind中.out文件的屏幕截图:

在此处输入图片说明

那应该提供有关PHP脚本效率的详细信息。您想要定位花费最长时间的事物。例如,您可以优化一个功能以花费一半的时间,但是最好的方法是优化在页面加载过程中调用数十次甚至数百次的功能。

如果您很好奇,这只是我自己编写的CMS的旧版本。


8
看起来很复杂,我听不懂
eric

您不了解哪一部分?设置还是分析数据?
亚历克峡谷

1
好了,设置不行,它将永远无法在我的服务器上运行,但是数据,我无法读取的所有小盒子
eric

13
因为我不使用Windows
eric

2
XDebug + KCacheGrind +1。它确实很有帮助,并且安装和使用起来非常容易。我已经使用它一段时间了,您会获得额外的好处-您逐渐熟悉它,可以将KCacheGrind与Valgrind(+ memgrind / callgrind)结合使用来分析更多其他语言(不仅是CPU时间)。
XzKto 2011年

16

尝试https://github.com/fotuzlab/appgati

它允许在代码中定义步骤,并报告两个步骤之间的时间,内存使用情况,服务器负载等。

就像是:

    $appgati->Step('1');

    // Do some code ...

    $appgati->Step('2');

    $report = $appgati->Report('1', '2');
    print_r($report);

样本输出数组:

Array
(
    [Clock time in seconds] => 1.9502429962158
    [Time taken in User Mode in seconds] => 0.632039
    [Time taken in System Mode in seconds] => 0.024001
    [Total time taken in Kernel in seconds] => 0.65604
    [Memory limit in MB] => 128
    [Memory usage in MB] => 18.237907409668
    [Peak memory usage in MB] => 19.579357147217
    [Average server load in last minute] => 0.47
    [Maximum resident shared size in KB] => 44900
    [Integral shared memory size] => 0
    [Integral unshared data size] => 0
    [Integral unshared stack size] => 
    [Number of page reclaims] => 12102
    [Number of page faults] => 6
    [Number of block input operations] => 192
    [Number of block output operations] => 
    [Number of messages sent] => 0
    [Number of messages received] => 0
    [Number of signals received] => 0
    [Number of voluntary context switches] => 606
    [Number of involuntary context switches] => 99
)

2
可爱的界面设计(我认为您是作者),谢谢!(并且感谢您使用“ ProperCase”;)方法名称(如SetMemory()),而不是难看但仍然无处不在的mixedCase()废话,这在PHP中实际上是毫无意义的。你可能太老了 ;))
Sz。

1
完全过时了,但花了几分钟,我把它变成了很好用的东西(即使在Windows中)。我将尝试看看是否可以提出拉取请求。
Tomas Gonzalez

7

我会调查xhprof。它是在cli上还是通过另一个sapi(例如fpm或fcgi甚至Apache模块)运行都没有关系。

关于xhprof的最好之处在于,它甚至足够适合在生产中运行。xdebug不能正常工作(我上次检查)。xdebug对性能有影响,而xhprof(我不会说没有)管理起来要好得多。

我们经常使用xhprof收集真实流量的样本,然后从那里分析代码。

尽管确实可以做到,但它确实不是一个基准,它可以为您提供时间和所有其他功能。它只是使分析生产流量非常容易,然后在收集到的调用图中深入到php函数级别。

一旦扩展被编译并加载,您就可以使用以下代码对代码进行性能分析:

xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

停止:

$xhprof_data = xhprof_disable();

然后将数据保存到文件或数据库中-无论浮起什么,并且不干扰正常的运行时。我们将其异步推送到S3以集中数据(以便能够查看所有服务器上的所有运行)。

github上代码包含一个xhprof_html文件夹,您将该文件夹转储到服务器上,并且只需进行最少的配置,就可以可视化所收集的数据并开始向下钻取。

HTH!


3

把它放在一个for循环做每一件事情1,000,000次,以获得更真实一些。并且仅在您实际要进行基准测试的代码之前启动计时器,然后在其之后记录结束时间(即,不要在之前启动计时器)session_start()

此外,请确保您要进行基准测试的每个功能的代码均相同,但您要计时的功能除外。

脚本的执行方式(cronjob,命令行中的php,Apache等)不应有任何区别,因为您只是在计时不同功能的速度之间的相对差异。因此,该比率应保持不变。

如果您正在运行基准测试的计算机发生了许多其他事情,如果在运行基准测试时碰巧另一个应用程序的CPU或内存使用量出现峰值,则这可能会影响基准测试结果。但是,只要您有大量资源可以在计算机上使用,那么我认为这不会成为问题。



0

埃里克,

您在问自己一个错误的问题。如果您的脚本在大约15毫秒内执行,那么它的时间就无关紧要了。如果您在共享服务上运行,则PHP映像激活将花费约100毫秒,如果完全缓存在服务器上,则读入脚本文件约30至50毫秒,如果从后端NAS服务器场加载脚本文件则可能需要1秒钟或更长时间。网络在加载页面家具上的延迟可能会增加很多秒。

这里的主要问题是用户对加载时间的理解:在单击链接和获得完整呈现的页面之间,他或她必须等待多长时间。看一下可以用作Ff或chrome扩展程序的Google Page Speed,以及深入探讨如何获得良好页面性能的Pagespeed文档。请遵循以下准则,并尝试使您的页面得分高于90/100。(与我的博客一样,Google主页得分为99/100)。这是获得良好的用户感知性能的最佳方法。


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.