【问题标题】:Accurate way to measure execution times of php scripts准确测量php脚本执行时间的方法
【发布时间】:2011-09-08 21:54:20
【问题描述】:

我想知道 PHP for 循环执行需要多少毫秒。

我知道通用算法的结构,但不知道如何在 PHP 中实现它:

Begin
init1 = timer(); // where timer() is the amount of milliseconds from midnight
the loop begin
some code
the loop end
total = timer() - init1;
End

【问题讨论】:

  • 如果您在生产中需要它,您可以摆弄大量的 microtime() 语句,但如果它只是用于测试,只需使用 xdebug's profiler 例如。没有杂乱的代码才是真正的加分项。

标签: php


【解决方案1】:

您可以为此使用microtime 函数。来自the documentation

microtime — 返回当前的 Unix 时间戳,单位为微秒


如果get_as_float 设置为TRUE,则microtime() 返回一个浮点数,它表示自Unix 纪元以来的当前时间,以秒为单位,精确到最接近的微秒。

示例用法:

$start = microtime(true);
while (...) {

}
$time_elapsed_secs = microtime(true) - $start;

【讨论】:

  • 如果你想用返回值做计算,你需要microtime(true)
  • 我知道这太晚了(差不多 4 年),但作为评论...使用这些计算(参数 get_as_floattrue)将为您提供 ,根据 PHP 文档。
  • @patrick 我就是这么说的:如果get_as_floattruemicrotime() 返回代表秒的值...
  • 虽然这是一篇很老的帖子,但我们应该提到这样一个事实,即返回的浮点数确实包含微秒...最好的解决方案是将其乘以 1000... 请参阅 stackoverflow.com/questions/3656713/… 作为例如..
  • "对于性能测量,建议使用 hrtime()。" php.net/manual/en/function.hrtime.php (PHP 7 >= 7.3.0, PHP 8)
【解决方案2】:

您可以通过以下方式使用microtime(true)

把它放在你的 php 文件的开头:

//place this before any script you want to calculate time
$time_start = microtime(true);

// 你的脚本代码放在这里

// do something

把它放在你的 php 文件的末尾:

// Display Script End time
$time_end = microtime(true);

//dividing with 60 will give the execution time in minutes other wise seconds
$execution_time = ($time_end - $time_start)/60;

//execution time of the script
echo '<b>Total Execution Time:</b> '.$execution_time.' Mins';

它会输出你的结果minutes

【讨论】:

    【解决方案3】:

    您可以使用来自$_SERVER 超全局数组的REQUEST_TIMEFrom the documentation:

    REQUEST_TIME
    请求开始的时间戳。 (自 PHP 5.1.0 起可用。)

    REQUEST_TIME_FLOAT
    请求开始的时间戳,微秒精度。 (自 PHP 5.4.0 起可用。)

    这样您就不需要在脚本的开头保存时间戳。你可以这样做:

    <?php
    // Do stuff
    usleep(mt_rand(100, 10000));
    
    // At the end of your script
    $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
    
    echo "Did stuff in $time seconds\n";
    ?>
    

    这里,$time 将包含自脚本启动以来经过的时间(以秒为单位),精度为微秒(例如,1.341 为 1 秒和 341 微秒)


    更多信息:

    PHP 文档$_SERVER variablesmicrotime function

    【讨论】:

    • 根据链接的文档,$time 将包含 的差异,而不是 微秒
    • @WimDeblauwe 澄清一下,是的,结果以秒为单位。但是用微秒精度。例如1.1 等于 1 秒 + 100 微秒。
    • 这是衡量响应时间的最佳方法
    • 这是最好的答案
    • 你们把微秒和毫秒搞混了。
    【解决方案4】:

    创建文件 loadtime.php

    <?php
    class loadTime{
        private $time_start     =   0;
        private $time_end       =   0;
        private $time           =   0;
        public function __construct(){
            $this->time_start= microtime(true);
        }
        public function __destruct(){
            $this->time_end = microtime(true);
            $this->time = $this->time_end - $this->time_start;
            echo "Loaded in $this->time seconds\n";
        }
    }
    

    比在你的脚本开头,在&lt;?php之后写include 'loadtime.php'; $loadtime=new loadTime();

    当页面最后加载时,会显示“Loaded in x seconds”

    【讨论】:

    • 整洁!但是如果你没有明确地销毁你的对象,输出将出现在关闭 &lt;/html&gt; 标记之后,这是无效的
    • @gondo 不,它将是秒(微秒表示为 sceconds 的十进制值)
    【解决方案5】:
    $start = microtime(true);
    for ($i = 0; $i < 10000; ++$i) {
        // do something
    }
    $total = microtime(true) - $start;
    echo $total;
    

    【讨论】:

      【解决方案6】:

      这是一个计时任何 PHP 代码执行的函数,就像 Python 的 timeit 模块所做的那样:https://gist.github.com/flaviovs/35aab0e85852e548a60a

      使用方法:

      include('timeit.php');
      const SOME_CODE = '
              strlen("foo bar");
      ';
      $t = timeit(SOME_CODE);
      print "$t[0] loops; $t[2] per loop\n";
      

      结果:

      $ php x.php 
      100000 loops; 18.08us per loop
      

      免责声明:我是此 Gist 的作者

      编辑:timeit 现在是https://github.com/flaviovs/timeit 上的一个独立的、自包含的项目

      【讨论】:

        【解决方案7】:

        microtime()

        【讨论】:

          【解决方案8】:

          您的想法是对的,但microtime() 函数可以提供更精确的时间。

          如果循环中的内容很快,则明显经过的时间可能为零。如果是这样,请围绕代码包装另一个循环并重复调用它。请务必将差异除以迭代次数以获得一次。我分析了需要 10,000,000 次迭代才能获得一致、可靠的计时结果的代码。

          【讨论】:

            【解决方案9】:

            这是一个非常简单简短的方法

            <?php
            $time_start = microtime(true);
            //the loop begin
            //some code
            //the loop end
            $time_end = microtime(true);
            $total_time = $time_end - $time_start;
            echo $total_time; // or whatever u want to do with the time
            ?>
            

            【讨论】:

            • 我想你错过了一些我在发布答案时测试过的代码
            • var_dump(microtime(true)); // float(1283846202.89) 当你使用 microtime true 时就是这样
            • 总时间也可以使用float
            【解决方案10】:

            我想我会分享我放在一起的功能。希望它可以节省您的时间。

            它最初用于跟踪基于文本的脚本的时间,因此输出为文本形式。但如果您愿意,可以轻松地将其修改为 HTML。

            它将为您计算自脚本启动以来以及每个步骤所花费的时间。它以 3 位小数精度格式化所有输出。 (低至毫秒。)

            将其复制到脚本顶部后,您只需将 recordTime 函数调用放在要计时的每个片段之后。

            将此复制到脚本文件的顶部:

            $tRecordStart = microtime(true);
            header("Content-Type: text/plain");
            recordTime("Start");
            
            function recordTime ($sName) {
              global $tRecordStart;
              static $tStartQ;
              $tS = microtime(true);
              $tElapsedSecs = $tS - $tRecordStart;
              $tElapsedSecsQ = $tS - $tStartQ;
              $sElapsedSecs = str_pad(number_format($tElapsedSecs, 3), 10, " ", STR_PAD_LEFT);
              $sElapsedSecsQ = number_format($tElapsedSecsQ, 3);
              echo "//".$sElapsedSecs." - ".$sName;
              if (!empty($tStartQ)) echo " In ".$sElapsedSecsQ."s";
              echo "\n";
              $tStartQ = $tS;
            }
            

            要跟踪经过的时间,只需执行以下操作:

            recordTime("What We Just Did")
            

            例如:

            recordTime("Something Else")
            //Do really long operation.
            recordTime("Really Long Operation")
            //Do a short operation.
            recordTime("A Short Operation")
            //In a while loop.
            for ($i = 0; $i < 300; $i ++) {
              recordTime("Loop Cycle ".$i)
            }
            

            输出如下:

            //     0.000 - Start
            //     0.001 - Something Else In 0.001s
            //    10.779 - Really Long Operation In 10.778s
            //    11.986 - A Short Operation In 1.207s
            //    11.987 - Loop Cycle 0 In 0.001s
            //    11.987 - Loop Cycle 1 In 0.000s
            ...
            //    12.007 - Loop Cycle 299 In 0.000s
            

            希望这对某人有所帮助!

            【讨论】:

              【解决方案11】:

              这是一个返回小数秒(即 1.321 秒)的实现

              /**
               * MICROSECOND STOPWATCH FOR PHP
               *
               * Class FnxStopwatch
               */
              class FnxStopwatch
              {
                  /** @var float */
                  private $start,
                          $stop;
              
                  public function start()
                  {
                      $this->start = self::microtime_float();
                  }
                  public function stop()
                  {
                      $this->stop = self::microtime_float();
                  }
                  public function getIntervalSeconds() : float
                  {
                      // NOT STARTED
                      if (empty($this->start))
                          return 0;
                      // NOT STOPPED
                      if (empty($this->stop))
                          return ($this->stop - self::microtime_float());
              
                      return $interval = $this->stop - $this->start;
                  }
              
                  /**
                   * FOR MORE INFO SEE http://us.php.net/microtime
                   *
                   * @return float
                   */
                  private static function microtime_float() : float
                  {
                      list($usec, $sec) = explode(" ", microtime());
              
                      return ((float)$usec + (float)$sec);
                  }
              }
              

              【讨论】:

                【解决方案12】:

                这是我测量平均时间的脚本

                <?php
                
                $times = [];
                $nbrOfLoops = 4;
                for ($i = 0; $i < $nbrOfLoops; ++$i) {
                    $start = microtime(true);
                    sleep(1);
                    $times[] = microtime(true) - $start;
                }
                
                echo 'Average: ' . (array_sum($times) / count($times)) . 'seconds';
                

                【讨论】:

                  【解决方案13】:

                  如果您希望以秒为单位显示该时间:

                  <?php
                  
                  class debugTimer
                  {
                      private $startTime;
                      private $callsCounter;
                  
                      function __construct()
                      {
                          $this->startTime = microtime(true);
                          $this->callsCounter = 0;
                      }
                  
                      public function getTimer(): float
                      {
                          $timeEnd = microtime(true);
                          $time = $timeEnd - $this->startTime;
                          $this->callsCounter++;
                          return $time;
                      }
                  
                      public function getCallsNumber(): int
                      {
                          return $this->callsCounter;
                      }
                  }
                  
                  $timer = new debugTimer();
                  usleep(100);
                  echo '<br />\n
                      ' . $timer->getTimer() . ' seconds before call #' . $timer->getCallsNumber();
                  
                  usleep(100);
                  echo '<br />\n
                      ' . $timer->getTimer() . ' seconds before call #' . $timer->getCallsNumber();
                  

                  【讨论】:

                    【解决方案14】:

                    我这样做的方式是使用hrtime,它是为性能指标而创建的,它独立于系统时间。 hrtime 不受系统时间更改的影响。 hrtime 自 PHP 7.3.0 起可用

                    $start = hrtime(true);
                    sleep(5); // do something, in your case a loop
                    $end = hrtime(true);
                    $eta = $end - $start;
                    // convert nanoseconds to milliseconds
                    $eta /= 1e+6;
                    echo "Code block was running for $eta milliseconds";
                    

                    输出:

                    Code block was running for 5000.495206 milliseconds

                    【讨论】:

                      【解决方案15】:

                      您可以使用单个函数找到以秒为单位的执行时间。

                      // ampersand is important thing here
                      function microSec( & $ms ) {
                          if (\floatval( $ms ) == 0) {
                              $ms = microtime( true );
                          }
                          else {
                              $originalMs = $ms;
                              $ms = 0;
                              return microtime( true ) - $originalMs;
                          }
                      }
                      
                      // you don't have to define $ms variable. just function needs
                      // it to calculate the difference.
                      microSec($ms);
                      sleep(10);
                      echo microSec($ms) . " seconds"; // 10 seconds
                      
                      for( $i = 0; $i < 10; $i++) {
                          // you can use same variable everytime without assign a value
                          microSec($ms);
                          sleep(1);
                          echo microSec($ms) . " seconds"; // 1 second
                      }
                      
                      for( $i = 0; $i < 10; $i++) {
                          // also you can use temp or useless variables
                          microSec($xyzabc);
                          sleep(1);
                          echo microSec($xyzabc) . " seconds"; // 1 second
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 2023-04-07
                        • 1970-01-01
                        • 2020-11-28
                        • 2011-11-14
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-04-22
                        • 2012-05-14
                        • 2020-01-22
                        相关资源
                        最近更新 更多