18

有时,我希望能够测量两段代码之间经过的时间。这仅仅是为了能够检测代码中的瓶颈并改进可以改进的地方。

我想设计一个这样的函数,该函数应该与一个全局变量一起使用,该变量会回显当前调用和上次调用之间经过的时间。

这样,您可以一个接一个地多次使用它。

并且该函数应该能够计算以秒为单位的差异,例如 0.1 秒或 0.3 秒等。

一个例子可能会更好地解释它。

echo time_elapsed();   

     // This echo outputs nothing cause this is the starting case. 
     // There is nothing to compare against. 

//
// 1st code section here
//

echo time_elapsed();  

      // This echo outputs 0.5 seconds. 
      // ...which means there has been 0.5 seconds passed 
      // ...since the last time time_elapsed() was fired

//
// 2nd code section here
//


echo time_elapsed()   

      // This echo outputs 0.2 seconds

//
// 3rd code section here 
//

echo time_elapsed()   

      // This echo outputs 0.1 seconds etc

我的问题是我需要使用哪些 PHP 实用程序(内置函数)来实现这种输出?

4

7 回答 7

23

像 XDebug/Zend Debugger 这样的调试器可以为您提供这种类型的洞察力(以及更多),但这里提示您如何编写这样的函数:

function time_elapsed()
{
    static $last = null;

    $now = microtime(true);

    if ($last != null) {
        echo '<!-- ' . ($now - $last) . ' -->';
    }

    $last = $now;
}

主要是函数microtime()是您进行时间计算所需的全部。为了避免使用全局变量,我在 elapsed 函数中使用了一个静态变量。或者,您可以创建一个简单的类,该类可以封装所需的变量并调用类方法来跟踪和输出时间值。

于 2012-06-27T22:00:53.730 回答
15

php doc s中的第一个示例:

<?php
/**
 * Simple function to replicate PHP 5 behaviour
 */
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

$time_start = microtime_float();

// Sleep for a while
usleep(100);

$time_end = microtime_float();
$time = $time_end - $time_start;

echo "Did nothing in $time seconds\n";
于 2012-06-27T22:00:24.770 回答
9

这些方面的东西应该起作用:

$start = microtime(true); 

// Do something
sleep(2);

$end = (microtime(true) - $start);
echo "elapsed time: $end";
于 2012-06-27T22:01:49.293 回答
2

其他因素会影响脚本的时间安排。例子:

  1. 复杂的代码和递归函数。
  2. 正在使用的 Web 服务器的类型,例如:共享 VS 专用主机。
于 2012-06-27T22:04:03.493 回答
2

相同的 draw010 函数(谢谢!),仅添加了自定义评论和时间显示,以微秒(us)为单位:

    function time_elapsed($comment) 
        {

        static $time_elapsed_last = null;
        static $time_elapsed_start = null;

        // $unit="s"; $scale=1000000; // output in seconds
        // $unit="ms"; $scale=1000; // output in milliseconds
        $unit="μs"; $scale=1; // output in microseconds

        $now = microtime(true);

        if ($time_elapsed_last != null) {
            echo "\n";
            echo '<!-- ';
            echo "$comment: Time elapsed: ";
            echo round(($now - $time_elapsed_last)*1000000)/$scale;
            echo " $unit, total time: ";
            echo round(($now - $time_elapsed_start)*1000000)/$scale;
            echo " $unit -->";
            echo "\n";
        } else {
            $time_elapsed_start=$now;
        }

        $time_elapsed_last = $now;
    }               

例子:

// Start timer
time_elapsed('');

// Do something
usleep(100);
time_elapsed('Now awake, sleep again');

// Do something
usleep(100);
time_elapsed('Game over');

输出:

<!-- Now awake, sleep again: Time elapsed: 100 us, total time: 100 us -->
<!-- Game over: Time elapsed: 100 us, total time: 200 us -->
于 2014-06-19T22:18:39.837 回答
2
<?php
$time_start = microtime(true);

// Sleep for a while (or your code which you want to measure)
usleep(100);

$time_end = microtime(true);
$time = $time_end - $time_start;

echo "Did nothing in $time seconds\n";

来源: http: //php.net/manual/en/function.microtime.php#example-2568

于 2017-06-06T07:17:03.987 回答
0

这个小而强大的类涵盖了我在开发中的分析需求:

<?php

class perflog {
    protected $perflog = [];

    public function start($tag) {
        if (!isset($this->perflog[$tag])) $this->perflog[$tag] = 0;
        $this->perflog[$tag] -= microtime(TRUE);
    }

    public function stop($tag) {
        $this->perflog[$tag] += microtime(TRUE);
    }

    public function results() {
        return $this->perflog;
    }
}

在这里查看它的实际应用。

它旨在通过后续start(<tag>)和调用来stop(<tag>)调用。它生成一个数组,其中包含您的代码在 start() 和 stop() 调用所包含的部分中花费的总时间,并带有匹配的标签。

start-stop 序列可以嵌套并且可以多次输入,从而总结了在封闭部分中花费的时间。

它的紧凑性确保了最小的性能影响。动态标签创建可用于让程序修改其监控的内容。通常,这会通过输出或存储功能进行扩展。

于 2017-12-30T20:25:35.257 回答