Boost之timer库

摘要 :

     Boost中使用timer和date_time库来完美地解决了C++无法高效地处理时间和日期的问题。在此文中,介绍timer库;而date_time库在后续博文中介绍。
     
 1. timer库的概述
     timer库是一个很小的库,提供简易的度量时间和进度显示功能,可以用于性能测试等需要计时的任务,对于大多数的情况它足够使用。
 
     timer库分为三个组件:
  •      计时器类timer
  •      progress_timer
  •      进度指示类progress_display
     1.1 timer
     timer类可以测量时间的流逝,是一个小型的计时器,提供毫秒级别的计时精度和操作函数,供程序员手工控制使用,就像是个方便的秒表。
     位于名字空间boost,为了使用timer组件,需要包含头文件<boost/timer.hpp>,即:
     #include <boost/timer.hpp>
     using namespace boost;
     1.1.2 用法
#include <boost/timer.hpp>
using namespace boost;
int main()
{
             timer t;
             cout << t.elapsed_max() / 3600 << "h" << endl;
             cout << t.elapsed_min() << "s" <<endl;
             cout << t.elapsed()<< "s" << endl;
}
     1.1.3 类摘要                                                         
             class timer
             {
             public:
                         timer() { _start_time = std::clock(); 
 
                         void   restart() { _start_time = std::clock(); 
     
                         double elapsed() const                  
                         { return  double(std::clock() - _start_time) / CLOCKS_PER_SEC; }
 
                         double elapsed_max() const
                         {
                                     return (double((std::numeric_limits<std::clock_t>::max)())
                                                 - double(_start_time)) / double(CLOCKS_PER_SEC);
                         }
 
                         double elapsed_min() const
                         { return double(1)/double (CLOCKS_PER_SEC); }
             private:
                         std::clock_t _start_time;//进程启动时的clock数
             }; 
timer的计时器使用了标准头文件<ctimer>里的std::clock()函数,它返回自进程启动以来的clock数,每秒的clock数则由宏
CLOCKS_PER_SEC定义。而在不同的操作系统中,CLOCKS_PER_SEC的值不同,比如在win32下,其值是1000,而在linux下为1000000,也就是说在win32中,精度为毫秒,而在linux中,精度为微秒。
 
 
注意:
  • 在timer没有定义析构函数, 这样做是正确和安全的。因为它仅有 一个类型为clock_t的成员变量_start_time,故没有必要实现析构函数来特意“释放资源”(也无资源可释放)。
  • timer接口简单,轻巧好用,适用于大部分的程序计时任务。但使用时,我们必须理解elapsed_min()和elapsed_max()这两个计时精度函数的定义,它们表明了timer的能力。timer不适合高精度的时间测量任务,它的精度依赖于操作系统和编译器,难以做到跨平台。
  • timer也不适合大跨度时间段的测量,可提供的最大时间跨度只有几百个小时,如果需要天,月等的时间跨度,则应使用date_time库。
1.2 progress_timer
它也是一个计时器,它继承自timer,会在析构时自动输出时间,省去了timer手动调用elapsed()的工作,是一个用于自动 计时相当方便的小工具。
process_timer位于名字空间boost,为了使用progress_timer组件,需要包含头文件<boost/progress.hpp>,即:
#include <boost/progress.hpp>
using namespace boost;
1.2.2 用法 
progress_timer继承了timer的全部能力,可以如timer那样使用,例如:
progress_timer  t; // 声明一个对象 
             ...             // 其他的操作
cout <<t.elapsed() << endl; // 输出流逝的时间
 但它有更简单的用法,不需要任何的调用, 只要声明progress_timer对象就可以了:
#include <boost/progress.hpp>
using namespace boost;
 
int main()
{
             boost::progress_timer t;
             // do something
}
这样,在程序退出时,导致了progress_timer析构时,会自动输出流逝的时间。显示输出如下:
0.23 s 
如果要在一个程序中测量多个时间,可以运用运用花括号{}限定progress_timer的生命期。
int main()
{
             {
                         boost::progress_timer t;
                         // do something
             }
             {
                         boost::progress_timer t;
                         // do something
             }
}
 
1.2.3 类摘要
progress_timer的类摘要如下:
class progress_timer : public timer, noncopyable
{
public:
             explicit progress_timer();
             progress_timer(std::ostream& os);
             ~progress_timer();
};
 
progress_timer继承自timer,因此它的接口与timer相同,也很简单。唯一需要注意的是构造函数progress_timer(std::ostream &os),它允许将析构时的输出定向到指定的IO流中,默认为std::cout。如果有特别的需求,可以用其他标准库输出流(ofstream,ostringstream)替换。
 
下面的代码把progress_timer的输出转移到了stringstream中,它可以被转换为字符串供其他应用使用:
stringstream ss;
{
             progress_timer t(ss); // 要求progress_timer输出到ss中,
} // progress_timer在这里析构,自动输出时间。
 
1.3 Progress_display
     Progress_display可以在控制台上显示程序的执行进度,如果程序执行很耗费时间,那么它能够提供一个友好的用户界面,不至于让用户在等待中失去信心,甚至怀疑程序的运行是否出了问题。
 
它位于名字空间boost,为了使用progress_display组件,需要包含头文件<boost/progress.hpp>,即:
#include <boost/progress.hpp>
using namespace boost;
 
1.3.2 类摘要
#include <boost/progress.hpp>
namespace boost {
             class progress_display : noncopyable {
             public:
                         progress_display( unsigned long expected_count );
                         // Effects: restart(expected_count),接受一个long型的参数,表示用于进度显示的基数,是最常用的创建方法
 
                         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.,返回当前计数,当计数达到expected_count时,表示任务完成,即100%
 
                                     unsigned long   expected_count() const
                                     //  Returns: The expected_count from the constructor.
 
             }; // progress_display
} // namespace boost
在使用时,如果调用 progress_display pd(unsigned long expected_count)显示的结果如:
如果调用progress_display pd(expected_count, "%%%","+++","???"),则会在上图的三行前加上"%%%","+++","???"。
 
注意:
它可以用于基本的进度显示,但是它有一个固有的缺陷:无法把进度显示输出与程序的输出分离。
 
 
 
 
 
posted @ 2012-11-19 19:52  loveyakamoz  阅读(9658)  评论(1编辑  收藏  举报