boost之Timer Library(计时器库)

转自:  http://www.c-view.org/tech/lib/cboost/timer.htm

 

Timer Library(计时器库)

翻译:tangtao  英文文档(English)

2002年01月11日

摘要

计时器库提供了计时器类--timer,计时器时间报告类--progress_timer,和进度条显示类progress_display。


timer库有两个头文件和三个类:

头文件功能
timer.hpptimer测量耗费时间
progress.hppprogress_timer测量耗费时间(使用timer),类析构时显示耗费时间
progress.hppprogress_display显示一个逐步滚动的进度条

上述三个类的设计目的相当明确--使程序员们在调试程序或是批处理作业中能够方便地调用计时 和进度报告功能。progress类的接口规范具有很强的通用性,能被其他一些实现所替换,以用在如GUI上。

timer类

timer类测量程序耗用时间。对于一些短期的定时任务很有帮助。这里的实现使用了C标准库 库的clock()函数,因此具有一定程度的可移植性,付出的代价却是--不确定的时间精度。 最大的测量时间可能是596.5小时(或小于此数)。由于这些限制,timer类不适合用在一些高可靠性、 高健壮性场合。

提要

#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

异常安全(Exception safety)

构造函数可能会抛出std::bad_alloc。其他成员函数不会抛出异常。

未来趋势

Ed Brey提出了一个非常合理的请求,应该提供一个方法检测elapsed()函数返回值的最大值, 但是这样一个检测函数却不具备可移植性。这个问题已向C语言的time扩展函数库工作组提出, 在不久将来会有一个解决方案。在此之前,可以使用elapsed_max()函数,它返回一个近似值。

progress_timer类

progress_timer自动测量程序耗费时间,并在对象析构时显示出耗费时间信息。 在提供的实现里默认向std::cout输出字符信息。

progress_timer类经常用在统计程序执行所耗费时间。一个简单的例子:

#include <boost/progress.hpp>
int main()
{
   progress_timer t;  // start timing
   // do something ...
   return 0;
}

它产生适当的输出,如:

1.23 s

注意:“s”是国际标准计量单位秒的缩写。

提要

#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

异常安全

构造函数可能会抛出std::bad_alloc。其他成员函数不会抛出异常。

progress_display类

progress_display类以适当的形式在适当的位置,显示一个进度条。它很适合用在人们需要了解程序运行进度的一些场合。

例如:需要对一个std::map<>类型的big_map变量进行一个非常冗长时间的计算, 下面的代码可以显示出整个计算的进度:

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

当70%的数据被处理后,整个进度显示如下:

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

异常安全

除了count() 和 expected_count(),其他成员函数均有输出动作,因此理论上可能会抛出异常。实际中,如此的异常抛出一般不太可能,一但有异常发生也许就意味有比较严重的问题在等着你。注意这里没有一个显式的析构函数,因此它不会抛出异常。

历史

这几个类源自程序员们使用了多年的老的C++和C代码。在Boost的邮件列表上,Reid Sweatman建议从比较专用的progress类中分离出相对通用的timer类。Sean Corfield建议允许向任何ostream的派生类进行输出。Dave Abrahams、Valentin Bonnard、Ed Brey,Andy Glew和Dietmar Kuhl提供了有用的注释。Ed Brey建议提供timer::elapsed_max()函数。John Maddock建议提供timer::elapsed_min()。Toon Knapen建议提供可选的打头字符串(leading strings),用于标记进度显示。

来龙去脉

timer类的早期版本声明和实现是分离的。但这样会给那些不愿意建构库的人带来麻烦。 建构DLL时也有困难(因为可能会关联引用不同编译器编译的库)。 这就造成明明可以使用这些类的地方却无法使用。因此现在的实现代码全部改成了inline形式。

曾有几个请求,想在不同的系统平台用特殊的系统API实现高性能timer。John Maddock 曾提交了一个Win32 API的实现版本。测试表明它的精度非常高,但有时反应时间却比std::clock() 函数慢很多,这实在是太糟了。此外,这样做还会导致非常依赖操作系统版本(WINNT、WIN95等) 和编译器(Microsoft和Borland的编译器通过了测试)。因此,std::clock()函数比各平台独有的timer API更加值得信赖。





©2001-2002 C-View.ORG All Rights Reserved.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值