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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM