摘要 :
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, "%%%","+++","???"),則會在上圖的三行前加上"%%%","+++","???"。注意:它可以用於基本的進度顯示,但是它有一個固有的缺陷:無法把進度顯示輸出與程序的輸出分離。
