6

I have created a benchmark class that allows the user to insert for example

$timer->checkpoint('1');

to check out some code for time,memory consumption and such.... and at the end of the code if she/he wants to test it she/he has to insert

$result=$timer->result();

this gives out some data to public function result() like e.g. memory usage (using memory_get_peak_usage) and time consumption (microtime()).

This all works just fine for me.

But how can I use the combination of existing built-in php functions to get a value that can be considered a CPU consumption?

It has been quite easy to calculate how much time has been spent on a certain piece of code using the built-in functions, but I've been having trouble thinking of a way how to get the CPU consumption for a certain piece of code.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Rene
  • 622
  • 3
  • 11
  • 27
  • Does this help? http://stackoverflow.com/questions/4705759/how-to-get-cpu-usage-and-ram-usage-without-exec – David Weinraub Dec 07 '11 at 12:41
  • Not really. I have researched through SO and googled alot, and I think I came to a solution...I'm building it right now and when I'm done I am going to post what I have tried to do. I am using this php function in hope that it will work - getrusage – Rene Dec 07 '11 at 12:48
  • ru_utime— A struct timeval field containing the amount of user time, in seconds, that the process has used. User time is CPU time spent executing the user program, rather than in kernel system calls. ru_stime— A struct timeval field containing the amount of system time, in seconds, that the process has used. System time is the CPU time spent executing system calls on behalf of the process.These are the two values you get from an array in a getrusage() function (built-in PHP). Basicly you have to divide the System time with the User time in order to get the processor consumption at that moment. – Rene Dec 08 '11 at 07:36

3 Answers3

6

Hate to answer my own question but I did a lot of research, and here I go... Basically what I did was this...

        $dat=getrusage();
        foreach ($dat as $key => $val) {
            $usertime= $dat['ru_utime.tv_usec'];
            $systemtime= $dat['ru_stime.tv_usec'];
            $finalresultcpu= ($systemtime + $usertime);
        }
        $this->_cpuTrackers[$name]=$finalresultcpu;
        return $this;
                                              }

As you can see I used a getrusage php built-in function. Which gives out an array with a whole bunch of info, of which most was pretty useless to me, except ru_utime.tv_usec(user time) and ru_stime.tv_usec(system time). To see how much CPU power the script has consumed, we need to look at the 'user time' and 'system time' values and as you can see in the code, add it to get the time which is in fact a cpu usage.

Rene
  • 622
  • 3
  • 11
  • 27
  • 1
    It's perfectly legitimate to answer your own question _and_ accept it.[There's even a badge for it](http://stackoverflow.com/badges/14/self-learner). :) – Herbert Jan 20 '12 at 11:10
  • Thanks Herbert...it's nice to get a tap on the back once in a while :-D. It's especially flattering to get one from a knowledgeable like yourself – Rene Jan 20 '12 at 11:36
  • Why do you divide system time by user time? It is not a ratio. User time is the cpu time used by your code. System time is the cpu time used by the system on your code's behalf. If anything, they should be added together; not divided. http://stackoverflow.com/a/556411/20801 – Andrew Ensley Dec 21 '12 at 17:22
  • Hey Andrew, thx for taking the time to look into this, I'll try to correct the answer ASAP. BTW Merry Christmas ;) – Rene Dec 23 '12 at 14:08
  • I would be more then happy if you could offer your answer. I would gladly accept it :) – Rene Dec 25 '12 at 23:56
  • 1
    I would just change this line: `$finalresultcpu= ($systemtime/$usertime)` to this: `$finalresultcpu= ($systemtime + $usertime)` Then you will have the exact amount of time execution took (not a percentage). – Andrew Ensley Jan 01 '13 at 17:54
  • 2
    Thanks for the example. I would remove the `foreach` - you can access the `$dat['ru_utime.tv_usec']` directly without the need of a `foreach`. – tftd Mar 19 '13 at 15:15
  • 1
    I think ru_utime.tv_usec is only the microsecond part that remains after subtracting the seconds part, that is you should add ru_utime.tv_sec*1000000. PHP documentation is unclear about this, but I never ever get a value over 1000000 even when the code runs for several seconds. Anyway, hard to tell since getrusage returns completely unreliable values that sometimes are even over three times the elapsed time (which is physically impossible) – matteo Apr 16 '13 at 01:05
  • hm...it worked for me at the time - but thanks for the input Matteo! – Rene Apr 17 '13 at 14:10
  • I would like to point out that the foreach loop in this code isn't accomplishing anything and should be removed. – Ben Zittlau Dec 20 '13 at 22:33
1
function cpu_usage(){
    static $R=0;
    $r=$R;
    $R=getrusage();
    $R= $R['ru_utime.tv_sec']*1000000+$R['ru_utime.tv_usec']+
        $R['ru_stime.tv_sec']*1000000+$R['ru_stime.tv_usec'];
    return $R-$r;
}

Usage:

cpu_time(); // optionally initiating, to measure time from this point,
            // not from the script's beginning
// doing some stuff here
echo cpu_time()." elapsed\n";
// doing yet some stuff here
echo cpu_time()." elapsed\n";

In simple cases it gives the same, as microtime, but with less precision. The same function for microtime:

function stopwatch(){
    static $time=0;
    $prev=$time;
    $time=microtime(true);
    return $time-$prev;
}

Of coarse, not to use like this:

stopwatch();
f(); // some function, which calls `stopwatch` in itself too
echo stopwatch();
Miguel
  • 11
  • 2
0

And how about..?

$pid = getmypid();
$cpu = exec("ps hup $pid|awk '{print $3}'");