PHP में स्क्रिप्ट निष्पादन समय को ट्रैक करना


289

PHP को CPU की उस समय की राशि को ट्रैक करना होगा जो किसी विशेष स्क्रिप्ट ने max_execution_time की सीमा को लागू करने के लिए उपयोग की है।

क्या स्क्रिप्ट के अंदर इस तक पहुंचने का कोई तरीका है? मैं अपने परीक्षणों के साथ कुछ लॉगिंग को शामिल करना चाहता हूं कि वास्तविक PHP में कितना सीपीयू जलाया गया था (जब स्क्रिप्ट बैठी है और डेटाबेस के लिए इंतजार कर रहा है तो समय नहीं बढ़ाया गया है)।

मैं एक लिनक्स बॉक्स का उपयोग कर रहा हूं।

जवाबों:


237

Unixoid सिस्टम पर (और साथ ही Windows पर php 7+ में), तो आप उपयोग कर सकते हैं 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";

ध्यान दें कि यदि आपको हर परीक्षा के लिए php उदाहरण दिया जा रहा है तो आपको अंतर की गणना करने की आवश्यकता नहीं है।


क्या स्क्रिप्ट के प्रारंभ में मूल्य से अंत में घटाया जाना चाहिए? अगर मैं नहीं कर रहा हूँ मैं वास्तव में कुछ अजीब संख्याएँ हो रही हूँ। एक पेज की तरह, जिसे उत्पन्न करने में 0.05 सेकंड का समय लगा है, यह कह रहा है कि 6s CPU समय लिया ... क्या यह सही है? यहां देखें: blog.rompe.org/node/85
डैरिल हेन

@ डार्लिन हेन: ओह, और आपको अजीब परिणाम मिलते हैं क्योंकि आप इसके बजाय स्ट्रिंग संयोजन का उपयोग कर रहे हैं;)
फिहग

@phihag मुझे अजीब समय भी देता है, कि एक पेज ने गणना में 40 सेकंड लिया लेकिन 2 सेकंड में लोड किया गया। यह संख्या 1.4 सेकंड और 40 सेकंड के बीच कूद जाती है
टिमो हुओवेनन

1
@TimoHuovinen क्या मूल्य वास्तव में utime/ stime/ दीवार घड़ी समय के लिए मिलता है ? और क्या आप एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण के लिए एक लिंक पोस्ट कर सकते हैं जो इस व्यवहार को दर्शाता है? OS / php वर्जन / वेबसर्वर वर्जन किस पर है? किसी भी मामले में, आप एक नया प्रश्न पोस्ट करना चाहते हैं और इसे यहां लिंक कर सकते हैं।
फ़िहग

4
बस एक छोटा सा अपडेट जोड़ना: यह फ़ंक्शन अब विंडोज पर भी समर्थित है।
अंकुश

522

यदि आपको सीपीयू निष्पादन समय के बजाय दीवार-घड़ी का समय चाहिए, तो गणना करना सरल है:

//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 otherwise seconds
$execution_time = ($time_end - $time_start)/60;

//execution time of the script
echo '<b>Total Execution Time:</b> '.$execution_time.' Mins';
// if you get weird results, use number_format((float) $execution_time, 10) 

ध्यान दें कि इसमें समय शामिल होगा कि PHP बाहरी संसाधनों जैसे डिस्क या डेटाबेस के लिए प्रतीक्षा कर रहा है, जिसका उपयोग max_execution_time के लिए नहीं किया जाता है।


38
हाय - यह 'वालकॉक टाइम' को ट्रैक करता है - सीपीयू समय को नहीं।
15:15 बजे फॉक्स

18
बिल्कुल सही, मैं एक Wallclock समय ट्रैकिंग समाधान के लिए देख रहा था।
समि

118

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);

जैसा कि बताया गया है, यह 'वालकॉक टाइम' नहीं 'सीपीयू टाइम' है


74

सबसे आसान तरीका:

<?php

$time1 = microtime(true);

//script code
//...

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

9
यह तालल7860 के उत्तर से कैसे भिन्न है ...?
बेनामेटिस

@webeno वह विभाजित नहीं करता है 60.. वास्तव में कोई अंतर नहीं है।
A1rPun

[कैसे 2] इस उत्तर में कोई गिरावट नहीं है? यह उत्तर के समान है।
टोडुआ

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

मुझे सेकंड में परिणाम नहीं मिला

आपको PHP 5.4.0
Joyal

29

मैंने फ़िहाग उत्तर से एक एक्ज़ीक्यूशन टाइम क्लास बनाया है जिसका उपयोग आप आउट ऑफ़ बॉक्स कर सकते हैं:

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;

नोट: PHP 5 में, गेट्रेज फ़ंक्शन केवल यूनिक्स-ओआईडी सिस्टम में काम करता है। PHP 7 के बाद से, यह विंडोज पर भी काम करता है।


2
नोट: विंडोज पर getrusageकेवल PHP 7 के बाद से काम करता है
मार्टिन वैन Driel

@MartinvanDriel मैंने नोट जोड़ा। धन्यवाद
हामिद Tavakoli

3
मुझे लगता है कि यदि आप कंस्ट्रक्टर में शुरू करते हैं, और टॉगिंग में समाप्त होते हैं, तो प्रत्येक उपयोग को कोड की 2 कम लाइनों की आवश्यकता होगी।
ओओपी के

13

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/ )


11

यदि आप सेकंड आउटपुट को स्वरूपित करते हैं, तो यह पूर्ववर्ती होने जा रहा है:

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

छप जाएगा

Process took 6.45 seconds.

इससे काफी बेहतर है

Process took 6.4518549156189 seconds.

9

सबसे सस्ता और सबसे गंदा तरीका यह है microtime()कि आप अपने कोड में उन स्थानों पर कॉल करें जहां आप बेंचमार्क करना चाहते हैं। डेटाबेस प्रश्नों के ठीक पहले और उसके ठीक बाद करें और अपने स्क्रिप्ट निष्पादन समय के बाकी हिस्सों से उन अवधि को निकालना आसान है।

एक संकेत: आपके PHP के निष्पादन का समय शायद ही कभी होने वाला है जो आपकी स्क्रिप्ट को टाइमआउट बनाता है। यदि स्क्रिप्ट का समय समाप्त हो जाता है तो यह लगभग हमेशा बाहरी संसाधन के लिए एक कॉल होने वाला है।

PHP microtime प्रलेखन: http://us.php.net/microtime


8

मुझे लगता है कि आपको xdebug देखना चाहिए। प्रोफाइलिंग विकल्प आपको कई प्रक्रिया संबंधी वस्तुओं को जानने की दिशा में एक शुरुआत देगा।

http://www.xdebug.org/


1
बस सुनिश्चित करें कि आप बहुत सारे वेबसाइट के साथ उत्पादन सर्वर पर xdebug स्थापित नहीं करते हैं। यह लॉगिंग की एक बड़ी मात्रा का उत्पादन करता है और एक छोटे एसएसडी ड्राइव को अभिभूत कर सकता है।
कॉरगलोर

8

मिनट और सेकंड दिखाने के लिए आप इसका उपयोग कर सकते हैं:

    $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

2

मैंने एक फ़ंक्शन लिखा जो शेष निष्पादन समय की जांच करता है।

चेतावनी: निष्पादन समय की गिनती विंडोज और लिनक्स प्लेटफॉर्म पर अलग है।

/**
 * 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.
    }
}

2

$_SERVER['REQUEST_TIME']

वह भी देखें। अर्थात

...
// your codes running
...
echo (time() - $_SERVER['REQUEST_TIME']);

दिलचस्प $_SERVER['REQUEST_TIME']बात यह भी है कि php-cli (जहाँ कोई सर्वर नहीं है) में उपलब्ध है
hanshenrik

1

आप केवल अपनी स्क्रिप्ट के कुछ हिस्सों का निष्पादन समय जानना चाह सकते हैं। समय के हिस्सों या एक पूरी स्क्रिप्ट का सबसे लचीला तरीका 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

एक विकल्प के रूप में आप इस लाइन को अपने कोड ब्लॉक में डाल सकते हैं और 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-kcacheindind देखें


0

हामिद के जवाब पर और विस्तार करते हुए, मैंने एक सहायक वर्ग लिखा, जिसे शुरू किया जा सकता है और बार-बार रोका जा सकता है (लूप के अंदर प्रोफाइलिंग के लिए)।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.