我想知道对PHP脚本进行基准测试的最佳方法是什么。无论是cron作业,还是网页或Web服务都无关紧要。
我知道我可以使用microtime但是它真的给了我PHP脚本的实时时间吗?
我想在PHP中测试和基准测试不同的函数,它们做同样的事情。例如,preg_match
vs strpos
或domdocument
vs 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左右。
有更好的方法吗?
答案 0 :(得分:118)
如果您确实想要对真实世界的代码进行基准测试,请使用Xdebug和XHProf等工具。
Xdebug非常适合您在开发/暂存工作时,XHProf是一个很好的生产工具,可以安全地在那里运行(只要您阅读说明)。任何单个页面加载的结果都不会像看到你的代码如何执行那样相关,同时服务器也会受到重创,而且资源也会变得稀缺。这提出了另一个问题:你在CPU上遇到了瓶颈吗?内存? I / O?
您还需要查看脚本中运行的代码,以及脚本/页面的提供方式。你使用什么Web服务器?举个例子,我可以认真地让nginx + PHP-FPM执行mod_php + Apache,这反过来会因使用一个好的CDN而无法提供静态内容。
接下来要考虑的是您要优化的内容?
前者可以通过像抓取发送到浏览器的所有资源这样做来帮助,但这样做(在某些情况下)会使你远离实现后者。
希望上述所有内容都可以帮助表明精心隔离的“实验室”测试不会反映您在制作中遇到的变量和问题,并且您必须确定您的高级目标是什么,然后您可以做什么到达那里,然后开始微观/早熟优化route to hell。
答案 1 :(得分:71)
要确定完整脚本在服务器上运行的速度,您可以使用大量工具。首先确保您的脚本(例如preg_match vs strpos)必须输出相同的结果才能使测试合格。
您可以使用:
答案 2 :(得分:26)
您需要查看Xdebug,更具体地说,Xdebug's profiling capabilities。
基本上,您启用了分析器,每次加载网页时,它都会创建一个可以使用WinCacheGrind或KCacheGrind读取的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的旧版本。
答案 3 :(得分: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
)
答案 4 :(得分: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();
然后将数据保存到文件或数据库中 - 无论你的boath是什么,都不会中断通常的运行时。我们异步将其推送到S3以集中数据(以便能够查看来自我们所有服务器的所有运行)。
code on github包含一个xhprof_html文件夹,您可以在服务器上转储该文件夹,只需最少的配置,您就可以看到所收集的数据并开始向下钻取。
HTH!
答案 5 :(得分:3)
将它放在一个for
循环中,每次执行1,000,000次以获得更真实的数字。并且只在您实际想要进行基准测试的代码之前启动计时器,然后记录刚刚结束的结束时间(即不要在session_start()
之前启动计时器。
同时确保每个要进行基准测试的功能的代码相同,但您正在计时的功能除外。
如何执行脚本(cronjob,来自命令行的php,Apache等)不应该有所不同,因为你只计算不同函数的速度之间的相对差异。所以这个比例应该保持不变。
如果运行基准测试的计算机还有许多其他事情发生,如果在基准测试运行时,如果其他应用程序的CPU或内存使用率出现峰值,则可能会影响基准测试结果。但只要你有足够的资源在电脑上,我就不会认为这会是一个问题。
答案 6 :(得分:1)
一个好的开始是使用xdebugs探查器 http://xdebug.org/docs/profiler
设置和使用可能不是最容易的事情,但是一旦你掌握了它,大量的数据和易于查看是不可替代的。
答案 7 :(得分:0)
埃里克,
你问自己错误的问题。如果你的脚本在大约15毫秒内执行,那么它的时间基本上是无关紧要的。如果您在共享服务上运行,那么PHP映像激活将花费大约100毫秒,如果在服务器上完全缓存,则读取脚本文件~30-50毫秒,如果从后端NAS服务器场加载,可能需要1秒或更长时间。加载页面家具时网络延迟可能会增加很多秒。
这里的主要问题是用户对加载时间的感知:他或她在点击链接和获得完全呈现的页面之间需要等待多长时间。查看可以用作Ff或chrome扩展名的Google Page Speed,以及深入讨论如何获得良好页面性能的Pagespeed文档。请遵循以下指南,并尝试将您的网页分数提高到90/100以上。 (谷歌主页得分为99/100,我的博客也是如此)。这是获得良好的用户感知性能的最佳方式。
答案 8 :(得分:0)
关注PHP代码并与link进行交叉检查也是很好的,以确保您的编码本身不会对应用程序的性能造成干扰。
答案 9 :(得分:0)
我的答案来自:https://stackoverflow.com/a/28868536/3066563
<?php
function yourFunction(){
echo 'Code Im benchmarking';
}
$time_start = microtime(true);
$times=0; // This couldn't be tough
while($times<1000)
{
yourFunction();
$times++;
}
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "Did yourFunction in $time seconds\n";
?>
只需将yourFunction中的代码更改为基准。