【问题标题】:measuring the elapsed time between code segments in PHP测量PHP中代码段之间的经过时间
【发布时间】:2012-06-29 10:13:10
【问题描述】:

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

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

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

并且该函数应该能够计算以秒为单位的差异,例如 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 实用程序(内置函数)来实现这种输出?

【问题讨论】:

  • 就我个人而言,我只是将 microtime() 或类似函数的输出记录在 san 数组中,然后再解析

标签: php time


【解决方案1】:

来自php docs中的第一个示例:

<?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";

【讨论】:

  • 而不是你的 microtime_float 函数,只需使用 microtime(true) 你会得到一个浮点数.. php.net/microtime
【解决方案2】:

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

function time_elapsed()
{
    static $last = null;

    $now = microtime(true);

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

    $last = $now;
}

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

【讨论】:

  • 我认为静态变量只保存在一个函数中,并且在整个脚本中是全局的,例如,如果一个函数中有静态 $a = 4,如果你在函数外回显 $a 你会得到一个错误,但是如果你设置了全局 $a,并且你在函数之外回显它,你会得到 4,另外,一个静态变量值会被保存以备下次使用 ex: static $a = 1; $a++;回声 $a;当您再次使用该功能时,它会回显 2,对于冗长而不清楚的评论表示抱歉:)
  • 当变量被声明为static 时,它是函数的局部变量,但在函数调用之间不会丢失其值。在类中使用时,其值在类的所有实例之间共享。
【解决方案3】:

按照这些思路应该可以工作:

$start = microtime(true); 

// Do something
sleep(2);

$end = (microtime(true) - $start);
echo "elapsed time: $end";

【讨论】:

    【解决方案4】:

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

    1. 复杂的代码和递归函数。
    2. 正在使用的 Web 服务器的类型,例如:共享 VS 专用主机。

    【讨论】:

      【解决方案5】:

      相同的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 -->
      

      【讨论】:

      • 非常喜欢。添加以秒为单位的显示选项可能是个好主意; ->&lt;!-- Game over: Time elapsed: 0.1 sec us, total time: 0.2 sec us --&gt;。另外,us 在这里代表什么?
      • @Average Joe 谢谢。 μs(希腊语 mu - s)停留微秒 = 1/1,000,000 秒。这是microtime 的本机精度。添加了以秒和毫秒为单位显示经过时间的选项
      【解决方案6】:
      <?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

      【讨论】:

        【解决方案7】:

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

        <?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;
            }
        }
        

        See it in action here.

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-07
          • 1970-01-01
          • 2013-01-05
          • 1970-01-01
          • 2017-07-13
          • 2023-03-26
          • 2014-09-05
          相关资源
          最近更新 更多