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_displayProgress_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 ignoreconst std::string & s1 = "\n", //leading stringsconst 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_countunsigned 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, "%%%","+++","???"),则会在上图的三行前加上"%%%","+++","???"。注意:它可以用于基本的进度显示,但是它有一个固有的缺陷:无法把进度显示输出与程序的输出分离。