1

Is there a way to measure the amount/length of time a web request spends doing I/O?

By that, I mean the actual amount of time the current thread (or it's delegation) has spent utilizing the hardware.

As for measuring CPU time, there's a function getrusage() for it:

<?php

$a = getrusage();
f();
$b = getrusage();

$sec = ($b['ru_utime.tv_sec'] - $a['ru_utime.tv_sec']) + ($b['ru_stime.tv_sec'] - $a['ru_stime.tv_sec']);
echo 'It took ~' . $sec . 's of CPU time.';

function f(){
    for($x=0;$x<120000000;++$x){
        // busy loop
    }
}

Is there a such a function for measuring I/O?

Sample usage of said function:

<?php

$credits_remaining = 8500;

$a = Time_Spent_On_Hard_Disk_So_Far();
Get_File_From_Hard_Disk($credits_remaining); // limit request to $credits_remaining number of seconds
$b = Time_Spent_On_Hard_Disk_So_Far();
$time_spent = $b - $a;

echo "Time spent on hard disk: ", $time_spent;
$credits_remaining -= $time_spent;

(A C solution would be fine, as long as we can call it from PHP without suffering from severe overheads.)

Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • 1
    Save microtime as variable at the top of a script and then after doing all the stuff, capture microtime again and then subtract first from second and you have your runtime. – Charlotte Dunois Dec 16 '14 at 11:31
  • 1
    @CharlotteDunois, Doesn't this give us [wall time](http://stackoverflow.com/q/12392278/632951) instead of I/O time? – Pacerier Dec 16 '14 at 14:21

1 Answers1

0

In your particular scenario, I'd get a microtime[stamp] before you start your operation(s), do the difference with another microtime[stamp], store the results in an array with metadata that explains what the metric refers to, and finally store that information in a data store, SOMEWHERE (database, txt file, session, etc.).

It's most likely the best (easiest) way to track that kind of information and have your code maintain portability across numerous operating environments.

/**
 *  Get Micro Time
 *
 *  Returns the current (epoch) time with micro seconds.
 *
 *  @param [in] $elapsed %REF% of difference since last execution
 *  @return | FLOAT time with micro seconds from epoch
 */
function microtime(&$elapsed = null) {

    static $previous = null;

    list($micro, $epoch) = explode(" ", microtime());

    $now = round(floatval($epoch.substr($micro, 1)), 3);

    if ($previous) {
        $elapsed = round($now - $previous,3);
    }

    $previous = $now;

    return $now;

}
Erutan409
  • 730
  • 10
  • 21
  • Thanks for the code example, but since this solution relies on `microtime`, doesn't it give us [wall time](http://stackoverflow.com/questions/27503523/how-to-measure-time-spent-doing-i-o-in-php/28436025#comment-43443574) instead of I/O time? – Pacerier Feb 11 '15 at 03:22
  • After doing some brief research on wall time (admittedly, I wasn't familiar with the concept until now), I'd say that if you absolutely need to measure separate threads, traffic lanes, etc., you may consider some sort of auditing software that can adequately track/measure those variables. Otherwise, if you're looking for a round about way of getting a baseline for your application speed efficiency, I'd go with the aforementioned solution. You could wrap the function around individual components of your code to get those metrics. Hence, my suggestion, previously, with tracking meta data. – Erutan409 Feb 11 '15 at 03:54
  • But using wall time to measure I/O time will give us very inaccurate results. E.g. when a thread is blocked, the wall clock runs but it isn't actually spending any time on the hard disk. – Pacerier Feb 11 '15 at 04:40
  • 1
    You are correct, sir. That function wouldn't give you the specific disk I/O time. I'm thinking that might be OS dependent. I know for Windows you'd hook on to procmon.exe and [more than likely] write a separate app that logs that I/O. I doubt you'd [easily] be able to track that kind of information in your PHP code. I'd like to see a solution for that, though, if someone has one. – Erutan409 Feb 11 '15 at 14:18