The timer library provides two headers and three classes:
Header Class Functionality timer.hpp timer Measure elapsed time. progress.hpp progress_timer Measure elapsed time (using timer), display on destruction. progress.hpp progress_display Display an indication of progress toward a known goal.
The objective in designing these classes was fairly limited - they are intended for simple uses like timing and reporting progress for programmer's tests or batch job streams. The specifications of the progress classes are worded in very general terms to permit alternate implementations such as for graphical user interfaces.
Class timer measures elapsed time. It is generally useful for minor timing tasks. Its supplied implementation offers moderate portability at the cost of depending on the unknown accuracy and precision of the C Standard Library clock() function. The maximum measurable elapsed time may be as low as 596.5 hours (or even less) for the supplied implementation. Because of these limitations, this timer cannot be depended upon to be robust, and should not be used if that is of any concern.
#include <boost/timer.hpp> namespace boost { class timer { public: timer(); // postcondition: elapsed()==0 // compiler generated copy constructor, copy assignment, and dtor apply void restart(); // post: elapsed()==0 double elapsed() const; // return elapsed time in seconds double elapsed_max() const; // return estimated maximum value for elapsed() // Portability warning: elapsed_max() may return too high a value on systems // where std::clock_t overflows or resets at surprising values. double elapsed_min() const; // return minimum value for elapsed() }; // timer } // namespace boost
The constructors may throw std::bad_alloc
. No other member
functions throw exceptions.
There was a very reasonable request from Ed Brey for a method of determining the maximum value which may be returned by elapsed(), but there isn't a way to do so portably. The issue has been raised with the group working on extended time functionality for the C language. A solution may be years in the future. In the meantime, elapsed_max() provides an approximation.
Class progress_timer automatically measures elapsed time, and then on destruction displays an elapsed time message at an appropriate place in an appropriate form. The supplied implementation defaults to a character display on std::cout.
Class progress_timer is often used to time program execution. Its use is as simple as:
#include <boost/progress.hpp> int main() { progress_timer t; // start timing // do something ... return 0; }
Which will produce some appropriate output, for example:
1.23 s
Note that "s" is the official System International d'Unités abbreviation for seconds.
#include <boost/progress.hpp> namespace boost { class progress_timer : public timer, noncopyable { public: progress_timer(); progress_timer( std::ostream& os ); // os is hint; implementation may ignore ~progress_timer(); }; // progress_display } // namespace boost
The constructors may throw std::bad_alloc
. No other member
functions throw exceptions.
Class progress_display displays an appropriate indication of progress toward a predefined goal at an appropriate place in an appropriate form. This meets a human need to know if a program is progressing.
For example, if a lengthy computation must be done on a std::map<> named big_map, the follow code would display an indication of progress:
progress_display show_progress( big_map.size() ); for ( big_map_t::iterator itr = big_map:begin(); itr != big_map.end(); ++itr ) { // do the computation ... ++show_progress; }
After 70% of the elements have been processed, the display might look something like this:
0% 10 20 30 40 50 60 70 80 90 100% |----|----|----|----|----|----|----|----|----|----| ************************************
#include <boost/progress.hpp> namespace boost { class progress_display : noncopyable { public: progress_display( unsigned long expected_count ); // Effects: restart(expected_count) progress_display( unsigned long expected_count, std::ostream& os, // os is hint; implementation may ignore const std::string & s1 = "\n", //leading strings const std::string & s2 = "", const std::string & s3 = "" ) // Effects: save copy of leading strings, restart(expected_count) void restart( unsigned long expected_count ); // Effects: display appropriate scale on three lines, // prefaced by stored copy of s1, s2, s3, respectively, from constructor // Postconditions: count()==0, expected_count()==expected_count unsigned long operator+=( unsigned long increment ) // Effects: Display appropriate progress tic if needed. // Postconditions: count()== original count() + increment // Returns: count(). unsigned long operator++() // Returns: operator+=( 1 ). unsigned long count() const // Returns: The internal count. unsigned long expected_count() const // Returns: The expected_count from the constructor. }; // progress_display } // namespace boost
All member functions except count() and expected_count() do output, and so in theory may throw exceptions. In practice it seems an exception being thrown is pretty unlikely, and probably implies such serious problems that an exception is warranted. Note that there is no explicit destructor, so the destructor throwing is not an issue.
These classes are descended from older C++ and C functionality found useful by programmers for many years. Via the Boost mailing list, Reid Sweatman suggested separating the more widely useful timer class from the more targeted progress classes. Sean Corfield suggested allowing output to any ostream. Dave Abrahams, Valentin Bonnard, Ed Brey, Andy Glew, and Dietmar Kühl also provided useful comments. Ed Brey suggested timer::elapsed_max(). John Maddock suggested timer::elapsed_min(). Toon Knapen suggested the optional leading strings, to allow for labeling the progress display
The early versions of the timer classes had separate implementation files. This caused problems for users not wishing to build libraries, caused difficulties building DLL's (because of cascaded use of other libraries which in turn brought illuminated compiler deficiencies), and caused the classes not to be used even when clearly applicable. Thus the implementation was changed to all inline code.
There have been several requests for platform specific implementations to use supposedly high-performance timers from the operating system API. John Maddock submitted an implementation using the Win32 API. Tests showed that while the precision of these timers was high, the latency was sometimes very much higher than for the std::clock() function, and that is very bad. Furthermore, results using the Win32 API were very dependent on both the compiler (Microsoft and Borland were tested) and the operating system version (Windows NT, Windows 95, etc.) Thus the std::clock() function was much more reliable, and so was retained even on this platform with its own timer API.
© Copyright Beman Dawes 1999. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. The software described is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.
Revised January 11, 2002