天天看點

怎麼計時程式運作的時間

【問題描述】程式運作時間是程式設計的一項重要名額,如何測算程式的運作時間呢?

【解析】

測試函數

[html]  view plain copy

  1. #include <math.h>  
  2. void function()  
  3. {  
  4.     unsigned int i,j;  
  5.     double y;  
  6.     for(i=0;i<1000;i++)  
  7.         for(j=0;j<1000;j++)  
  8.             y=sin((double)i);  
  9. }  

方法1 如果在QT中,利用QTime,其精度為ms級----------在QT中使用。

[html]  view plain copy

  1. #include <QDebug>  
  2. #include <QTime>  
  3. QTime time;  
  4. time.start();  
  5. function();  
  6. qDebug()<<time.elapsed()/1000.0<<"s";  

運作結果:0.109 s

方法2 利用gettimeofday(),其精度為us級----------C語言實作,在Linux下使用。

[html]  view plain copy

  1. #include <QDebug>  
  2. #include <sys/time.h>  
  3. struct timeval tpstart,tpend;  
  4. float timeuse;  
  5. gettimeofday(&tpstart,NULL);  
  6. function();  
  7. gettimeofday(&tpend,NULL);  
  8. timeuse=(1000000*(tpend.tv_sec-tpstart.tv_sec) + tpend.tv_usec-tpstart.tv_usec)/1000000.0;  
  9. qDebug()<<timeuse<<"s";  

運作結果:0.109375 s

方法3 利用clock(),其精度為ms級----------C++實作,在VC和QT中也可以使用。

[html]  view plain copy

  1. #include <QDebug>  
  2. #include <sys/time.h>  
  3. double time_Start = (double)clock();  
  4. function();  
  5. double time_End = (double)clock();  
  6. qDebug()<<(time_End - time_Start)/1000.0<<"s";  

運作結果:0.11 s

方法4 利用windows.h(VC)函數,其精度為us級----------在VC和QT中使用。

[html]  view plain copy

  1. #include <QDebug>  
  2. #include <windows.h>  
  3. LARGE_INTEGER litmp;  
  4. LONGLONG Qpart1,Qpart2,Useingtime;  
  5. double dfMinus,dfFreq,dfTime;  
  6. //獲得CPU計時器的時鐘頻率  
  7. QueryPerformanceFrequency(&litmp);//取得高精度運作計數器的頻率f,機關是每秒多少次(n/s),  
  8. dfFreq = (double)litmp.QuadPart;  
  9. QueryPerformanceCounter(&litmp);//取得高精度運作計數器的數值  
  10. Qpart1 = litmp.QuadPart; //開始計時  
  11. function(); //待測試的計算函數等  
  12. QueryPerformanceCounter(&litmp);//取得高精度運作計數器的數值  
  13. Qpart2 = litmp.QuadPart; //終止計時  
  14. dfMinus = (double)(Qpart2 - Qpart1);//計算計數器值  
  15. dfTime = dfMinus / dfFreq;//獲得對應時間,機關為秒,可以乘1000000精确到微秒級(us)  
  16. Useingtime = dfTime*1000000;  
  17. qDebug()<<dfTime<<"s";  

運作結果:0.107415 s

【代碼清單】 

[html]  view plain copy

  1. #include <QDebug>  
  2. #include <QTime>  
  3. #include <sys/time.h>  
  4. #include <windows.h>  
  5. #include <math.h>  
  6. void function();  
  7. int main(void)  
  8. {  
  9.     qDebug()<<"-------------------------------";  
  10.     //-1-  
  11.     QTime time;  
  12.     time.start();  
  13.     function();  
  14.     qDebug()<<time.elapsed()/1000.0<<"s";  
  15.     //-2-  
  16.     struct timeval tpstart,tpend;  
  17.     float timeuse;  
  18.     gettimeofday(&tpstart,NULL);  
  19.     function();  
  20.     gettimeofday(&tpend,NULL);  
  21.     timeuse=(1000000*(tpend.tv_sec-tpstart.tv_sec) + tpend.tv_usec-tpstart.tv_usec)/1000000.0;  
  22.     qDebug()<<timeuse<<"s";  
  23.     //-3-  
  24.     double time_Start = (double)clock();  
  25.     function();  
  26.     double time_End = (double)clock();  
  27.     qDebug()<<(time_End - time_Start)/1000.0<<"s";  
  28.     //-4-  
  29.     LARGE_INTEGER litmp;  
  30.     LONGLONG Qpart1,Qpart2,Useingtime;  
  31.     double dfMinus,dfFreq,dfTime;  
  32.     //獲得CPU計時器的時鐘頻率  
  33.     QueryPerformanceFrequency(&litmp);//取得高精度運作計數器的頻率f,機關是每秒多少次(n/s),  
  34.     dfFreq = (double)litmp.QuadPart;  
  35.     QueryPerformanceCounter(&litmp);//取得高精度運作計數器的數值  
  36.     Qpart1 = litmp.QuadPart; //開始計時  
  37.     function(); //待測試的計算函數等  
  38.     QueryPerformanceCounter(&litmp);//取得高精度運作計數器的數值  
  39.     Qpart2 = litmp.QuadPart; //終止計時  
  40.     dfMinus = (double)(Qpart2 - Qpart1);//計算計數器值  
  41.     dfTime = dfMinus / dfFreq;//獲得對應時間,機關為秒,可以乘1000000精确到微秒級(us)  
  42.     Useingtime = dfTime*1000000;  
  43.     qDebug()<<dfTime<<"s";  
  44.     return 0;  
  45. }  
  46. void function()  
  47. {  
  48.     unsigned int i,j;  
  49.     double y;  
  50.     for(i=0;i<1000;i++)  
  51.         for(j=0;j<1000;j++)  
  52.             y=sin((double)i);  
  53. }  
  1. ----------------------------------------------------------------------------
  2. 另外,方法2可具體參考:
  3. 在測試程式時,我們往往需要了解程式執行所需的時間,在C語言可以使用函數gettimeofday來得到時間,它的調用格式是:

    #include <sys/time.h>int gettimeofday(struct timeval *tv,struct timezone *tz);int settimeofday(const struct timeval *tv , const structtimezone *tz);

    其中結構timeval的定義為:

    strut timeval {long tv_sec;long tv_usec;};

    可以看出,使用這種方式計時,精度可達微秒。

    進行計時的時候,我們需要前後調用兩次gettimeofday,然後計算中間的內插補點,執行個體代碼如下:

    ************************************

    gettimeofday( &start, NULL );

    foo(); //示例函數

    gettimeofday( &end, NULL);

    timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec -start.tv_usec;

    timeuse /=1000000;

    ***********************************

    其中start,end 是結構體所定義的timeval型。

  4. --------------------------------------------------------------------------------
  5. 方法3可具體參考:
  6. 我現在用C++語言寫了一段程式,想計算這段程式運作的準确時間,這是要用于跟其它實驗結果作對比的,是以要精确到毫秒,C++程式運作時間 确實很難掌握啊!

    C++程式運作時間中的計時函數是clock(),而與其相關的資料類型是clock_t。在MSDN中,查得對clock函數定義如下:  

    1. #ifndef   _CLOCK_T_DEFINED     
    2.  typedef   long   clock_t;     
    3.  #define   _CLOCK_T_DEFINED     
    4.  #endif    
    這個函數傳回從“開啟這個程式程序”到“程式中調用clock()函數”時之間的CPU時鐘計時單元(clock   tick)數,在MSDN中稱之為挂鐘時間(wal-clock)。其中clock_t是用來儲存時間的資料類型,在time.h檔案中,我們可以找到對 它的定義:  
    1. #ifndef   _CLOCK_T_DEFINED     
    2.  typedef   long   clock_t;     
    3.  #define   _CLOCK_T_DEFINED     
    4.  #endif    
    很明顯,clock_t是一個長整形數。在time.h檔案中,還定義了一個常量CLOCKS_PER_SEC,它用來表示一秒鐘會有多少個時鐘計時單元,其定義如下:   
    1. int   main(   void   )     
    2. {     
    3.       long         i   =   10000000L;     
    4.       clock_t   start,   finish;     
    5.       double     duration;     
    6.       /*   測量一個事件持續的時間*/     
    7.       printf(   "Time   to   do   %ld   empty   loops   is   ",   i   );     
    8.       start   =   clock();     
    9.       while(   i--   )             ;     
    10.       finish   =   clock();     
    11.       duration   =   (double)(finish   -   start)   /   CLOCKS_PER_SEC;     
    12.       printf(   "%f   seconds"n",   duration   );     
    13.       system("pause");     
    14. }    
    可以看到每過千分之一秒(1毫秒),調用clock()函數傳回的值就加1。下面舉個例子,你可以使用公式clock()/CLOCKS_PER_SEC來計算一個程序自身的C++程式運作時間 :
    1. void   elapsed_time()     
    2.   {     
    3.   printf("Elapsed   time:%u   secs."n",clock()/CLOCKS_PER_SEC);     
    4.   }    
    當然,你也可以用clock函數來計算你的機器運作一個循環或者處理其它事件到底花了多少時間:  
    1. int   main(   void   )     
    2. {     
    3.       long         i   =   10000000L;     
    4.       clock_t   start,   finish;     
    5.       double     duration;     
    6.       /*   測量一個事件持續的時間*/     
    7.       printf(   "Time   to   do   %ld   empty   loops   is   ",   i   );     
    8.       start   =   clock();     
    9.       while(   i--   )             ;     
    10.       finish   =   clock();     
    11.       duration   =   (double)(finish   -   start)   /   CLOCKS_PER_SEC;     
    12.       printf(   "%f   seconds"n",   duration   );     
    13.       system("pause");     
    14. }    
    上面我們看到時鐘計時單元的長度為1毫秒,那麼計時的精度也為1毫秒,那麼我們可不可以通過改變CLOCKS_PER_SEC的定義,通過把它定義的大一 些,進而使計時精度更高呢?通過嘗試,你會發現這樣是不行的。在标準C++程式運作時間 中,最小的計時機關是一毫秒。