如何衡量用 PHP 编写的代码的速度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1200214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 01:30:00  来源:igfitidea点击:

How can I measure the speed of code written in PHP?

phptestingperformancemeasurement

提问by M. A. Kishawy

How can I say which class of many (which all do the same job) execute faster? is there a software to measure that?

我怎么能说哪一类(都做同样的工作)执行得更快?有没有软件可以测量?

回答by Pascal MARTIN

You have (at least)two solutions :

您有(至少)两个解决方案:

The quite "na?ve" one is using microtime(true) tobefore and after a portion of code, to get how much time has passed during its execution ; other answers said that and gave examples already, so I won"t say much more.

相当“天真”的是使用 microtime(true) tobefore 和 after 一部分代码,以获取执行过程中已经过去了多少时间;其他答案已经说过并且已经给出了例子,所以我不会说更多。

This is a nice solution if you want to benchmark a couple of instructions ; like compare two types of functions, for instance -- it's better if done thousands of times, to make sure any "perturbating element" is averaged.

如果您想对几个指令进行基准测试,这是一个不错的解决方案;例如,比较两种类型的函数——最好进行数千次,以确保对任何“扰动元素”进行平均。

Something like this, so, if you want to know how long it take to serialize an array :

像这样,所以,如果你想知道序列化一个数组需要多长时间:

$before = microtime(true);

for ($i=0 ; $i<100000 ; $i++) {
    serialize($list);
}

$after = microtime(true);
echo ($after-$before)/$i . " sec/serialize\n";

Not perfect, but useful, and it doesn't take much time to set up.

不完美,但很有用,而且设置时间也不长。





The other solution, that works quite nice if you want to identify which function takes lots of time in an entire script, is to use :

如果您想确定哪个函数在整个脚本中花费了大量时间,另一个解决方案是使用:

  • The Xdebugextension, to generate profiling data for the script
  • Software that read the profiling data, and presents you something readable. I know three of those :
    • Webgrind; web interface ; should work on any Apache+PHP server
    • WinCacheGrind; only on windows
    • KCacheGrind; probably only Linux and linux-like ; That's the one I prefer, btw
  • Xdebug的扩展,以生成脚本分析数据
  • 读取分析数据并为您呈现可读内容的软件。我知道其中三个:
    • 网络研磨;网页界面;应该适用于任何 Apache+PHP 服务器
    • WinCacheGrind; 只在窗户上
    • KCacheGrind; 可能只有 Linux 和 linux-like ;那是我更喜欢的,顺便说一句

To get profiling files, you have to install and configure Xdebug ; take a look at the Profiling PHP Scriptspage of the documentation.

要获取分析文件,您必须安装和配置 Xdebug ;查看文档的Profiling PHP Scripts页面。

What I generally do is not enable the profiler by default (it generates quite big files, and slows things down), but use the possibility to send a parameter called XDEBUG_PROFILEas GET data, to activate profiling just for the page I need.
The profiling-related part of my php.ini looks like this :

我通常做的不是默认启用分析器(它会生成相当大的文件,并且会减慢速度),而是使用发送称为XDEBUG_PROFILEGET 数据的参数的可能性,以仅针对我需要的页面激活分析。
我的 php.ini 中与分析相关的部分如下所示:

xdebug.profiler_enable = 0              ; Profiling not activated by default
xdebug.profiler_enable_trigger = 1      ; Profiling activated when requested by the GET parameter
xdebug.profiler_output_dir = /tmp/ouput_directory
xdebug.profiler_output_name = files_names

(Read the documentation for more informations)

(阅读文档了解更多信息)

This screenshot is from a C++ program in KcacheGrind : http://kcachegrind.sourceforge.net/html/pics/KcgShot3Large.gif
(source: sourceforge.net)

You'll get exactly the same kind of thing with PHP scripts ;-)
(With KCacheGrind, I mean ; WinCacheGrind is not as good as KCacheGrind...)

此屏幕截图来自 KcacheGrind 中的 C++ 程序:(来源:sourceforge.net您将使用 PHP 脚本获得完全相同的东西 ;-)(使用 KCacheGrind,我的意思是;WinCacheGrind 不如 KCacheGrind... )http://kcachegrind.sourceforge.net/html/pics/KcgShot3Large.gif



This allows you to get a nice view of what takes time in your application -- and it sometimes definitly helps to locate thefunction that is slowing everything down ^^

这使您可以很好地了解应用程序中需要花费时间的内容——有时它绝对有助于找到使一切变慢功能^^

Note that Xdebug counts the CPU time spent by PHP ; when PHP is waiting for an answer from a Database (for instance), it is not working ; only waiting. So Xdebug will think the DB request doesn't take much time !
This should be profiled on the SQL server, not PHP, so...

请注意,Xdebug 计算 PHP 花费的 CPU 时间;当 PHP 正在等待来自数据库的答案时(例如),它不起作用;只有等待。所以 Xdebug 会认为 DB 请求不需要太多时间!
这应该在 SQL 服务器上进行分析,而不是 PHP,所以......


Hope this is helpful :-)
Have fun !


希望这有帮助:-)
玩得开心!

回答by Scott Saunders

For quick stuff I do this (in PHP):

对于快速的东西,我这样做(在 PHP 中):

$startTime = microtime(true);
doTask(); // whatever you want to time
echo "Time:  " . number_format(( microtime(true) - $startTime), 4) . " Seconds\n";

You can also use a profiler like http://xdebug.org/.

您还可以使用像http://xdebug.org/这样的分析器。

回答by Nelson Teixeira

I've made a simple timing class, maybe it's useful to someone:

我做了一个简单的计时课,也许对某人有用:

class TimingHelper {

    private $start;

    public function __construct() {
        $this->start = microtime(true);
    }

    public function start() {
        $this->start = microtime(true);
    }

    public function segs() {
        return microtime(true) - $this->start;
    }

    public function time() {
        $segs = $this->segs();
        $days = floor($segs / 86400);
        $segs -= $days * 86400;
        $hours = floor($segs / 3600);
        $segs -= $hours * 3600;
        $mins = floor($segs / 60);
        $segs -= $mins * 60;
        $microsegs = ($segs - floor($segs)) * 1000;
        $segs = floor($segs);

        return 
            (empty($days) ? "" : $days . "d ") . 
            (empty($hours) ? "" : $hours . "h ") . 
            (empty($mins) ? "" : $mins . "m ") . 
            $segs . "s " .
            $microsegs . "ms";
    }

}

Use:

用:

$th = new TimingHelper();
<..code being mesured..>
echo $th->time();
$th->start(); // if it's the case
<..code being mesured..>
echo $th->time();

// result: 4d 17h 34m 57s 0.00095367431640625ms 

回答by na-98

2020 Update

2020 更新

It's been many years since I last answered this questions so I thought this deserves an update on the APM landscape.

自从我上次回答这个问题已经很多年了,所以我认为这值得对 APM 领域进行更新。

  • AppDynamics has been bought by Cisco and free forever account they used to offer has been taken out from their website.
  • NewRelic has dropped their pricing from $149/month/host to $25/month/host to compete with the new comer to the APM market, Datadog which offers $31/month/host.
  • Datadog APM features are still light and leaves much to be desired for. However, I see them enhancing and improving these throughout the next year.
  • Ruxit has been bought by Dynatrace. No shocker here as Ruxit is built by ex Dynatrace Employees. This allowed Dynatrace to transform to a truly SaaS model for better. Say goodbye to that bulky Java client if you'd like to.
  • There are free/open-source options now as well. Checkout Apache Skywalkingwhich is very popular in China among their top tech companies and PinPointwhich offers a demo that you can try before installing. Both of these require you manage hosting so get ready to spin up few Virtual Machine and spend some time with installation and configuration.
  • I haven't tried either of these opensource APM solution so I'm in no position to recommend them, however, I've personally managed deploying all of these APM solutions for multiple organizations either on-premise or on cloud for hundreds of application/microservices. So I can say with confidence, you can't go wrong with any of the vendors if they fit your bill.
  • AppDynamics 已被 Cisco 收购,他们曾经提供的永久免费帐户已从其网站上删除。
  • NewRelic 已将其定价从 149 美元/月/主机降至 25 美元/月/主机,以与 APM 市场的新来者 Datadog 竞争,后者提供 31 美元/月/主机。
  • Datadog APM 功能仍然很简单,还有很多不足之处。但是,我看到他们在接下来的一年中增强和改进了这些。
  • Ruxit 已被 Dynatrace 收购。这里并不令人震惊,因为 Ruxit 是由前 Dynatrace 员工打造的。这让 Dynatrace 能够更好地转变为真正的 SaaS 模型。如果您愿意,请告别那个笨重的 Java 客户端。
  • 现在也有免费/开源选项。查看在china顶级科技公司中非常流行的Apache SkywalkingPinPoint,它提供了一个演示,您可以在安装前试用。这两者都需要您管理托管,因此准备启动一些虚拟机并花一些时间进行安装和配置。
  • 我还没有尝试过这些开源 APM 解决方案中的任何一个,所以我无法推荐它们,但是,我亲自为多个组织部署了所有这些 APM 解决方案,无论是在本地还是在云上,用于数百个应用程序/微服务。所以我可以自信地说,如果任何供应商符合您的要求,您都不会出错。



Originally Answered on October 2015最初于 2015 年 10 月回答

Here is a direct answer to your question

这是您问题的直接答案

is there a software to measure that?

有没有软件可以测量?

Yes, there is. I'm wondering why anyone hasn't mentioned it yet. Although the answers suggested above seems fine for a quick check but isn't scalable in the long run or for a bigger project.

就在这里。我想知道为什么还没有人提到它。尽管上面建议的答案对于快速检查来说似乎很好,但从长远来看或对于更大的项目而言,它是不可扩展的。

Why not use an Application Performance Monitoring (APM) tool which are build exactly for that and so much more. Check out NewRelic, AppDynamics, Ruxit (all have free version) to monitor the execution time, resource usage, throughput of every application to the method level.

为什么不使用专为此而构建的应用程序性能监控 (APM) 工具等等。查看 NewRelic、AppDynamics、Ruxit(都有免费版本)来监控每个应用程序到方法级别的执行时间、资源使用情况、吞吐量。

回答by tasmaniski

If you want to quick test performance of a framework, you can put in index.phpfile

如果你想快速测试一个框架的性能,你可以放入index.php文件

//at beginning
$milliseconds = round(microtime(true) * 1000);

//and at the end
echo round(microtime(true) * 1000) - $milliseconds;

Every time you will get execution time in milliseconds. Because microseconds is not too useful in testing a framework case.

每次你都会得到以毫秒为单位的执行时间。因为微秒在测试框架案例时不是很有用。

回答by Jason

I've been using XHProf lately http://pecl.php.net/package/xhprof. It was originally developed by Facebook and it comes with a decent web interface.

我最近一直在使用 XHProf http://pecl.php.net/package/xhprof。它最初由 Facebook 开发,并带有一个不错的 Web 界面。

回答by RafaSashi

I'd like to share with you a self made function I use to measure the speed of any existing function up to 10 arguments:

我想与您分享一个自制函数,我用来测量最多 10 个参数的任何现有函数的速度:

function fdump($f_name='', $f_args=array()){

    $f_dump=array();
    $f_result='';

    $f_success=false;

    $f_start=microtime();
    $f_start=explode(' ', $f_start);
    $f_start=$f_start[1] + $f_start[0];

    if(function_exists($f_name)){

        if(isset($f_args[0])&&is_array($f_args[0])){
            if($f_result=$f_name($f_args)){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[1])){
            if($f_result=$f_name($f_args[0])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[2])){
            if($f_result=$f_name($f_args[0],$f_args[1])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[3])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[4])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[5])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[6])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[7])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[8])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[9])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[10])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8],$f_args[9])){
                $f_success=true;
            }
        }
    }
    $f_end=microtime();
    $f_end=explode(' ', $f_end);
    $f_end=$f_end[1] + $f_end[0];

    $f_time=round(($f_end - $f_start), 4);
    $f_dump['f_success']=$f_success;
    $f_dump['f_time']=$f_time;
    $f_dump['f_result']=$f_result;

    var_dump($f_dump);exit;

    //return $f_result;

}

Example

例子

function do_stuff($arg1='', $arg2=''){
    return $arg1.' '.$arg2;
}

fdump('do_stuff',array('hello', 'world'));

Returns

退货

  array(3) {
    ["f_success"]=>
    bool(true)
    ["f_time"]=>
    float(0)            //too fast...
    ["f_result"]=>
    string(11) "hello world"
  }

回答by chaos

If it's something that can be tested outside the Web context, I just use the Unix timecommand.

如果它可以在 Web 上下文之外进行测试,我只使用 Unixtime命令。

回答by OverloadUT

Zend Studio has built in support for profiling using XDebug or ZendDebugger. It will profile your code, telling you exactly how long every function took. It's a fantastic tool for figuring out where your bottlenecks are.

Zend Studio 内置了对使用 XDebug 或 ZendDebugger 进行分析的支持。它会分析你的代码,告诉你每个函数花费的时间。这是找出瓶颈所在的绝佳工具。

回答by Alex

You can use basic stuff like storing timestamps or microtime() before and after an operation to calculate the time needed. That's easy to do, but not very accurate. Maybe a better solution is Xdebug, i've never worked with it but it seems to be the best-known PHP debugger/profiler I can find.

您可以在操作前后使用存储时间戳或 microtime() 等基本内容来计算所需的时间。这很容易做到,但不是很准确。也许更好的解决方案是Xdebug,我从未使用过它,但它似乎是我能找到的最著名的 PHP 调试器/分析器。