在PHP中跟踪脚本执行时间
PHP必须跟踪特定脚本为了执行max_execution_time限制而使用的CPU时间量。
有没有一种方法可以访问脚本的内部? 我想包括一些logging与我的testing有关多lessCPU在实际的PHP烧(时间不会增加,当脚本是坐着等待数据库)。
我正在使用Linux机器。
在unixoid系统上(以及Windows上的php 7.0.0),可以使用getrusage ,例如:
// Script start $rustart = getrusage(); // Code ... // Script end function rutime($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)); } $ru = getrusage(); echo "This process used " . rutime($ru, $rustart, "utime") . " ms for its computations\n"; echo "It spent " . rutime($ru, $rustart, "stime") . " ms in system calls\n";
请注意,如果您为每个testing生成一个php实例,则不需要计算差异。
如果您只需要挂钟时间,而不是CPU执行时间,那么计算起来很简单:
//place this before any script you want to calculate time $time_start = microtime(true); //sample script for($i=0; $i<1000; $i++){ //do anything } $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';
请注意,这将包括PHP正在等待外部资源(如磁盘或数据库)的时间,该时间不用于max_execution_time。
较短版本的talal7860的答案
<?php // At start of script $time_start = microtime(true); // Anywhere else in the script echo 'Total execution time in seconds: ' . (microtime(true) - $time_start);
正如所指出的那样,这是“挂钟时间”而不是“cpu时间”
最简单的方法是:
<?php $time1 = microtime(true); //script code //... $time2 = microtime(true); echo 'script execution time: ' . ($time2 - $time1); //value in seconds
<?php // Randomize sleeping time usleep(mt_rand(100, 10000)); // As of PHP 5.4.0, REQUEST_TIME_FLOAT is available in the $_SERVER superglobal array. // It contains the timestamp of the start of the request with microsecond precision. $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]; echo "Did nothing in $time seconds\n"; ?>
我用phihag的答案创build了一个ExecutionTime类,你可以使用开箱即用的方式:
class ExecutionTime { private $startTime; private $endTime; public function Start(){ $this->startTime = getrusage(); } public function End(){ $this->endTime = getrusage(); } 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->runTime($this->endTime, $this->startTime, "utime") . " ms for its computations\nIt spent " . $this->runTime($this->endTime, $this->startTime, "stime") . " ms in system calls\n"; } }
用法:
$executionTime = new ExecutionTime(); $executionTime->Start(); // code $executionTime->End(); echo $executionTime;
注意:getrusage函数只能在unixoid系统中运行,而在Windows 7.0.0中运行。
Gingerod在developerfusion.com给出了这个很好的答案:
<!-- put this at the top of the page --> <?php $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $starttime = $mtime; ;?> <!-- put other code and html in here --> <!-- put this code at the bottom of the page --> <?php $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; $totaltime = ($endtime - $starttime); echo "This page was created in ".$totaltime." seconds"; ;?>
从( http://www.developerfusion.com/code/2058/determine-execution-time-in-php/ )
我想你应该看看xdebug。 性能分析选项将帮助您了解许多与stream程相关的项目。
最便宜也最脏的方法就是在代码中想要进行基准testing的地方进行microtime()
调用。 在数据库查询之前和之后执行此操作,并且从脚本执行时间的其余部分中删除这些持续时间非常简单。
提示:你的PHP执行时间很less会让你的脚本超时。 如果脚本超时,则几乎总是要调用外部资源。
PHP microtime文档: http : //us.php.net/microtime
<?php $time1 = microtime(true); //script code //...for or if or any thing you want to know! $time2 = microtime(true); echo 'Total execution time: ' . ($time2 - $time1);//value in seconds ?>
您可能只想知道脚本部分的执行时间。 定时部分或整个脚本的最灵活的方法是创build3个简单的函数(这里给出的过程代码,但是可以通过将class timer {}放在它周围并进行一些调整来将它变成一个类)。 此代码有效,只需复制并粘贴并运行:
$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');
我写了一个函数,检查剩余的执行时间。
警告: 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. } }
作为替代scheme,您可以将这行代码放在代码块中,查看PHP日志,对于非常慢的函数,这非常有用:
trigger_error("Task done at ". strftime('%H:%m:%S', time()), E_USER_NOTICE);
对于严重的debugging使用XDebug + Cachegrind,请参阅https://blog.excess.net/2011/01/29/diagnosing-slow-php-execution-with-xdebug-and-kcachegrind/