2009-02-11 5 views
204

PHP doit suivre la quantité de temps processeur qu'un script particulier a utilisé pour appliquer la limite de durée maximale d'exécution.Suivi de l'heure d'exécution du script en PHP

Y a-t-il un moyen d'accéder à cela à l'intérieur du script? Je voudrais inclure un peu de journalisation avec mes tests sur la quantité de CPU qui a été gravée dans le PHP réel (le temps n'est pas incrémenté lorsque le script est assis et attend la base de données). J'utilise une machine Linux.

Répondre

156

Sur les systèmes unixoid (et en php 7.0.0 sur Windows aussi bien), vous pouvez utiliser getrusage, comme:

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

Notez que vous n'avez pas besoin de calculer une différence si vous générez une instance php pour chaque test.

+0

Si la valeur à la fin être soustrait de la valeur au début du script? Je reçois des chiffres vraiment bizarres si je ne le fais pas. Comme une page qui a pris 0.05 secondes pour générer c'est dire qu'il a fallu 6s de temps CPU ... est-ce correct? Voir ici: http://blog.rompe.org/node/85 –

+0

@Darryl Hein: Oh, et vous obtenez des résultats bizarres parce que vous utilisez la concaténation de chaînes au lieu de l'addition;) – phihag

+8

Depuis * .tv_usec est en microsecondes (1 000 000 par second) et * .tv_sec est en secondes, n'avez-vous pas besoin de multiplier par 1000000 (ou 1e6) au lieu de 1000? –

8

Le moyen le moins cher et le plus sale de le faire est simplement de faire des appels microtime() aux endroits dans votre code que vous voulez comparer. Faites-le juste avant et juste après les requêtes de la base de données et il est simple de supprimer ces durées du reste de votre temps d'exécution du script.

Un indice: votre temps d'exécution PHP sera rarement le facteur qui retardera votre script. Si un script arrive à expiration, il s'agira presque toujours d'un appel à une ressource externe.

PHP documentation microtime: http://us.php.net/microtime

8

Je pense que vous devriez regarder xdebug. Les options de profilage vous donneront une longueur d'avance vers la connaissance de nombreux éléments liés au processus.

http://www.xdebug.org/

+0

Assurez-vous de ne pas installer xdebug sur un serveur de production avec beaucoup de sites Web. Il produit une énorme quantité de journalisation et peut submerger un petit disque SSD. – Corgalore

361

Si tout ce que vous avez besoin est le temps mur-horloge, plutôt que le temps d'exécution du processeur, il est simple à calculer:

//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'; 
// in you get wierd result, use number_format((float) $execution_time, 10) 

Notez que cela inclut le temps que PHP est Attente en attente de ressources externes telles que des disques ou des bases de données, qui n'est pas utilisé pour max_execution_time.

+29

Hi: cette fonction permet de suivre l'heure de l'horloge et non l'heure du processeur. – twk

+6

Parfait, je cherchais une solution de suivi des temps d'horloge murale. – samiles

11

Gringod à developerfusion.com donne cette bonne réponse:

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

De (http://www.developerfusion.com/code/2058/determine-execution-time-in-php/)

27
<?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"; 
?> 
+0

Je n'ai pas obtenu le résultat en secondes –

+0

Vous devriez utiliser PHP 5.4.0 – Joyal

70

version plus courte de la réponse de 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); 

Comme l'a souligné, c'est 'heure de l'horloge' pas 'temps de processeur'

16

J'ai créé une classe ExecutionTime de réponse phihag que vous pouvez utiliser hors de la boîte:

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

utilisation:

$executionTime = new ExecutionTime(); 
$executionTime->Start(); 
// code 
$executionTime->End(); 
echo $executionTime; 

Remarque: la fonction getrusage ne fonctionne que dans les systèmes unixoid, et PHP 7.0.0 sur Windows.

+0

Note: Sur Windows 'getrusage' ne fonctionne que depuis PHP 7. –

+0

@MartinvanDriel J'ai ajouté la note. Merci – Hamid

59

La façon la plus simple:

<?php 

$time1 = microtime(true); 

//script code 
//... 

$time2 = microtime(true); 
echo 'script execution time: ' . ($time2 - $time1); //value in seconds 
1

Vous voudrez peut-être seulement de connaître le temps d'exécution des parties de votre script. La manière la plus flexible de créer des parties de temps ou un script entier est de créer 3 fonctions simples (code procédural donné ici mais vous pouvez le transformer en classe en mettant class timer {} autour de lui et en faisant quelques réglages). Ce code fonctionne, il suffit de copier et coller et exécuter:

$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'); 
1

J'ai écrit une fonction qui vérifie la durée d'exécution restante.

Avertissement: Le comptage du temps d'exécution est différent sur Windows et sur la plate-forme 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); 
} 

utilisant:

while (true) { 
    // so something 

    if (!isRemainingMaxExecutionTimeBiggerThan(5000)) { 
     // Time to die. 
     // Safely close DB and done the iteration. 
    } 
} 
6
<?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 
?> 
1

Il va être plus joli si vous formatez la seconde sortie comme:

echo "Process took ". number_format(microtime(true) - $start, 2). " seconds."; 

imprimera

Process took 6.45 seconds. 

Cela est beaucoup mieux que

Process took 6.4518549156189 seconds.