Отслеживание времени выполнения скрипта в PHP - PullRequest
252 голосов
/ 11 февраля 2009

PHP должен отслеживать количество процессорного времени, которое конкретный сценарий использовал для обеспечения ограничения max_execution_time.

Есть ли способ получить доступ к этому внутри скрипта? Я хотел бы включить в мои тесты некоторые записи о том, сколько ЦП было сожжено в реальном PHP (время не увеличивается, когда скрипт сидит и ожидает базу данных).

Я использую коробку Linux.

Ответы [ 16 ]

2 голосов
/ 27 сентября 2016

Я написал функцию, которая проверяет оставшееся время выполнения.

Предупреждение: Подсчет времени выполнения различен на Windows и на платформе Linux.

/**
 * Check if more that `$miliseconds` ms remains
 * to error `PHP Fatal error:  Maximum execution time exceeded`
 * 
 * @param int $miliseconds
 * @return bool
 */
function isRemainingMaxExecutionTimeBiggerThan($miliseconds = 5000) {
    $max_execution_time = ini_get('max_execution_time');
    if ($max_execution_time === 0) {
        // No script time limitation
        return true;
    }
    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        // On Windows: The real time is measured.
        $spendMiliseconds = (microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]) * 1000;
    } else {
        // On Linux: Any time spent on activity that happens outside the execution
        //           of the script such as system calls using system(), stream operations
        //           database queries, etc. is not included.
        //           @see http://php.net/manual/en/function.set-time-limit.php
        $resourceUsages = getrusage();
        $spendMiliseconds = $resourceUsages['ru_utime.tv_sec'] * 1000 + $resourceUsages['ru_utime.tv_usec'] / 1000;
    }
    $remainingMiliseconds = $max_execution_time * 1000 - $spendMiliseconds;
    return ($remainingMiliseconds >= $miliseconds);
}

Использование:

while (true) {
    // so something

    if (!isRemainingMaxExecutionTimeBiggerThan(5000)) {
        // Time to die.
        // Safely close DB and done the iteration.
    }
}
1 голос
/ 11 декабря 2015

Возможно, вы захотите узнать только время выполнения частей вашего скрипта. Самый гибкий способ для синхронизации частей или всего скрипта - это создание 3 простых функций (здесь приведен процедурный код, но вы можете превратить его в класс, поместив вокруг него таймер класса {} и сделав пару настроек). Этот код работает, просто скопируйте, вставьте и запустите:

$tstart = 0;
$tend = 0;

function timer_starts()
{
global $tstart;

$tstart=microtime(true); ;

}

function timer_ends()
{
global $tend;

$tend=microtime(true); ;

}

function timer_calc()
{
global $tstart,$tend;

return (round($tend - $tstart,2));
}

timer_starts();
file_get_contents('http://google.com');
timer_ends();
print('It took '.timer_calc().' seconds to retrieve the google page');
0 голосов
/ 04 апреля 2019

возвращаемое время (истина) - $ _SERVER ["REQUEST_TIME_FLOAT"];

0 голосов
/ 17 января 2019

Для отображения минут и секунд вы можете использовать:

    $startTime = microtime(true);
    $endTime = microtime(true);
    $diff = round($endTime - $startTime);
    $minutes = floor($diff / 60); //only minutes
    $seconds = $diff % 60;//remaining seconds, using modulo operator
    echo "script execution time: minutes:$minutes, seconds:$seconds"; //value in seconds
0 голосов
/ 09 декабря 2018

Более подробно остановившись на ответе Хамида, я написал вспомогательный класс, который можно запускать и останавливать повторно (для профилирования внутри цикла).

   class ExecutionTime
   {
      private $startTime;
      private $endTime;
      private $compTime = 0;
      private $sysTime = 0;

      public function Start(){
         $this->startTime = getrusage();
      }

      public function End(){
         $this->endTime = getrusage();
         $this->compTime += $this->runTime($this->endTime, $this->startTime, "utime");
         $this->systemTime += $this->runTime($this->endTime, $this->startTime, "stime");
      }

      private function runTime($ru, $rus, $index) {
         return ($ru["ru_$index.tv_sec"]*1000 + intval($ru["ru_$index.tv_usec"]/1000))
         -  ($rus["ru_$index.tv_sec"]*1000 + intval($rus["ru_$index.tv_usec"]/1000));
      }

      public function __toString(){
         return "This process used " . $this->compTime . " ms for its computations\n" .
                "It spent " . $this->systemTime . " ms in system calls\n";
      }
   }
0 голосов
/ 12 сентября 2017

В качестве альтернативы вы можете просто поместить эту строку в свои блоки кода и проверить логи php, для действительно медленных функций это довольно полезно:

trigger_error("Task done at ". strftime('%H:%m:%S', time()), E_USER_NOTICE); 

Для серьезной отладки используйте XDebug + Cachegrind, см. https://blog.nexcess.net/2011/01/29/diagnosing-slow-php-execution-with-xdebug-and-kcachegrind/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...