CPSC 427: Object-Oriented Programming
Michael J. Fischer
Clocks and Time Measurement
How to measure run time of a program
High resolution clocks
Measuring time in real systems
Demo: Stopwatch
Realtime
measurements
StopWatch is a class I wrote for measuring realtime performance of
code.
It emulates a stopwatch with 3 buttons: reset, start, and stop.
At any time, the watch displays the cumulative time that the stopwatch has been running.
HirezTime class
HirezTime is a wrapper class for the system-specific functions to read
the clock.
It hides the details of the underlying time representation and provides a
simple interface for reading, computing, and printing times and time
intervals.
HirezTime objects are intended to be copied rather than pointed at, and they try to behave like other numeric types.
Versions of HirezTime
There are two versions: 15-StopWatch (Linux/Unix/MacOSX) Function gettimeofday() returns the clock in a struct timeval, which consists of two long ints representing seconds and microseconds. The resolution of the clock is system-dependent, typically 1 millisecond. (See demo 15-StopWatch.) 15-StopWatch-hirez (Linux only) Function clock_gettime() returns the clock in a struct timespec, which consists of two long ints representing seconds and nanoseconds. The resolution of the clock is system-dependent and can be obtained with the clock_getres() function. (See demo 15-StopWatch-hirez.)
HirezTime structure
Printing a HirezTime number
Something seemingly simple like printing HirezTime values is not so simple. Naively, one might write:
where tv_sec and tv_usec are the seconds and microseconds fields of
a timeval structure.
If t represents 2 seconds and 27 microseconds, then what would print is
2.27, not the correct 2.000027.
The class contains a print function that fixes this problem.
StopWatch class
StopWatch contains five member variables to remember
All functions are inline to minimize inaccuracies of measurement due to the overhead within the stopwatch code itself.
Casting a StopWatch to a HirezTime
An operator extension defines a cast for reading the cumulative time from a stop watch:
operator HirezTime() const { return cumSpan;
}
Thus, if sw is a StopWatch,
cout << sw;
will print sw.cumSpan using sw.print().
Why it works
This works because operator<<() is not defined for righthand operands
of type StopWatch but it is defined for HirezTime.
The compiler then coerces sw to something that is acceptable to the <<
operator.
Because operator HirezTime() is defined for class StopWatch, the
compiler will invoke it to obtain a HirezTime object, for which << is
defined.
Note that a similar coercion happens when one writes
if(!in) {…}
to test if an istream object in is open for reading. Here, the istream object is coerced to a bool because operator bool() is defined inside the streams package.