【问题标题】:How to benchmark efficiency of PHP script如何对 PHP 脚本的效率进行基准测试
【发布时间】:2012-01-07 15:32:54
【问题描述】:

我想知道对我的 PHP 脚本进行基准测试的最佳方法是什么。无论是 cron 作业、网页还是 Web 服务。

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

我想测试和基准测试 PHP 中执行相同操作的不同函数。例如,preg_match vs strposdomdocument 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 左右。

有没有更好的办法?

【问题讨论】:

  • 阅读这篇文章:rakesh.sankar-b.com/2011/01/12/echo-print-which-is-fast-php - 希望对您有所帮助。
  • 0.015 秒。眼睛的平均眨眼速度为 0.3 秒。你真的、真的、真的需要提高那个速度吗?请问为什么?
  • @ben 这是一个例子,我的页面在 0.8 秒内加载,每小时有超过 50k 访问者我需要确保页面快速加载
  • @MarcB 亚马逊显然进行了测试,发现 100 毫秒的延迟会导致销售额下降 1%。对于像亚马逊这样的大型网站来说,这可能是数十亿美元。 highscalability.com/…
  • @ceejayoz 是的,如果你是亚马逊,那这是一个大问题,但如果你不是,那么要警惕为了它而追逐疯狂的页面加载时间。亚马逊做了他们的功课,因此可以很容易地证明花费 X 工时来挽回 Y 销售下降是合理的。这里的教训是做你自己的功课!

标签: php performance benchmarking microtime


【解决方案1】:

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

Xdebug 非常适合您在开发/暂存环境中工作,而 XHProf 是一款出色的生产工具,可以安全地在那里运行(只要您阅读说明)。任何单个页面加载的结果都不会像查看代码的执行情况那样相关,而服务器也正忙于做一百万个其他事情并且资源变得稀缺。这引发了另一个问题:您是否在 CPU 上遇到瓶颈?内存?输入输出?

您还需要不仅仅关注您在脚本中运行的代码,还需要了解您的脚本/页面的服务方式。您使用的是什么网络服务器?举个例子,我可以让 nginx + PHP-FPM 在性能上大大超过 mod_php + Apache,而后者又会因为使用好的 CDN 提供静态内容而受到攻击。

接下来要考虑的是您要优化什么?

  • 页面在用户浏览器中的呈现速度是 第一要务?
  • 正在尽快将发往服务器的每个请求都丢弃 以最小的 CPU 消耗为目标?

可以通过对发送到浏览器的所有资源进行 gzip 压缩等操作来帮助前者,但这样做可能(在某些情况下)会使您远离实现后者。

希望以上所有内容都可以帮助表明,仔细隔离的“实验室”测试不会反映您在生产中将遇到的变量和问题,并且您必须确定您的高级目标是什么,然后您可以做什么到达那里,然后再进行微/过早优化route to hell

【讨论】:

  • 如果这真的回答了你的问题 eric,我觉得你的问题措辞不正确(或者我可能只是读错了)。根据您的问题,听起来您想隔离在 PHP 中执行相同操作的不同方法,并确定哪个方法最快。但是,根据您接受并给予赏金的答案,您似乎对对整个 Web 堆栈进行负载测试更感兴趣——这是完全不同的事情。
  • Xdebug 不支持 Ioncube 编码脚本。你如何对这些脚本进行基准测试?
  • @BigSack 你在那儿有点靠自己,我从来没有尝试过分析任何像这样混淆的东西。我会先用 XHProf 试一试,因为那相对容易上手。您可能会发现 IonCube 完全干扰了任何非用户态分析器。
  • Nginx vs Apache 的说法有点偏颇。大多数人忽略了AllowOveride,导致 Apache 在每次请求时遍历整个目录以获取 .htaccess 文件。仅此一项就可以让 Apache 摆脱困境。
【解决方案2】:

要对完整脚本在服务器上的运行速度进行基准测试,您可以使用很多工具。首先确保您的脚本(例如 preg_match 与 strpos)必须输出相同的结果才能使您的测试合格。

你可以使用:

【讨论】:

    【解决方案3】:

    你会想看看Xdebug,更具体地说,Xdebug's profiling capabilities

    基本上,您启用分析器,每次加载网页时,它都会创建一个可以使用WinCacheGrindKCacheGrind 读取的缓存研磨文件。

    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。

    【讨论】:

    • 好像很复杂,一个都不懂
    • 你不明白哪一部分?设置或分析数据?
    • 好吧,设置不,它永远不会在我的服务器上工作,但数据,它所有的小盒子我都看不懂
    • 因为我不用windows
    • +1 用于 XDebug + KCacheGrind。它真的很有帮助,而且非常容易安装和使用。我已经使用它很长一段时间了,您可以获得额外的好处 - 您熟悉它,您可以使用 KCacheGrind 和 Valgrind (+memgrind/callgrind) 来分析更多其他语言(不仅是 CPU 时间)。
    【解决方案4】:

    试试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
    )
    

    【讨论】:

    • 可爱的界面设计(我看你是作者),谢谢! (感谢您使用“ProperCase”;)方法名称(如SetMemory())而不是丑陋但仍然无处不在的mixedCase() 废话,这在PHP 中实际上毫无意义。你可能太老了。 ;) )
    • 完全过时了,但几分钟后我把它变成了很好用的东西(即使在 Windows 中)。我会尝试看看是否可以提出拉取请求。
    【解决方案5】:

    我会调查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 以集中数据(以便能够查看来自我们所有服务器的所有运行)。

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

    HTH!

    【讨论】:

      【解决方案6】:

      将其放入for 循环中,对每件事进行 1,000,000 次以获得更实际的数字。并且仅在您实际要进行基准测试的代码之前启动计时器,然后在之后记录结束时间(即不要在 session_start() 之前启动计时器。

      还要确保您要进行基准测试的每个函数的代码都是相同的,但您正在计时的函数除外。

      脚本的执行方式(cronjob、命令行中的 php、Apache 等)应该不会产生影响,因为您只是在计算不同函数速度之间的相对差异。所以这个比例应该保持不变。

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

      【讨论】:

        【解决方案7】:

        埃里克,

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

        这里的主要问题是用户对加载时间的看法:他或她在点击链接和获得完全呈现的页面之间需要等待多长时间。查看Google Page Speed,您可以将其用作 Ff 或 chrome 扩展,以及深入讨论如何获得良好页面性能的 Pagespeed 文档。遵循这些准则并尝试让您的页面得分高于 90/100。 (谷歌主页得分 99/100 和我的博客一样)。这是获得良好用户感知性能的最佳方式。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-22
          • 2023-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多