在C++程序的性能分析中,其中重要的一項就是程序的運行時間。雖然程序的運行速度與計算機的配置、計算機的當前狀態等有很大關系,但在相對一致的外部環境下,程序運行時間的長短在很大程度上是可以反映程序效率的。
1.一般計時方法
在ctime頭文件中,C++提供了計時函數 clock() ,其返回數據類型為 clock_t。
typedef long clock_t;
clock()函數返回從“開啟程序進程”到“程序中調用clock()函數”這段時間里,CPU時鍾計時單元(clock tick)的數目,在MSDN中稱之為掛鍾時間(wal-clock)。
在ctime文件中,還定義了一個常量CLOCKS_PER_SEC,它用來表示一秒內有多少個CPU時鍾計時單元。
通過clock()/CLOCKS_PER_SEC便可以得到進程的運行時間,一般CLOCKS_PER_SEC的值為1000,可見計時精度可達小數點后3位(毫秒級)。
#define CLK_TCK CLOCKS_PER_SEC
計時的簡單示例如下
/* *作者:侯凱 *說明:clock()計時函數 *日期:2013-6-6 */ #include <ctime> //計時用的頭文件 #include <iostream> using namespace std; int main() { long i = 10000000L; clock_t start, end; start = clock(); while( i-- );//需要計時的程序段 end = clock(); printf("The time was: %f\n", (double)(end - start) / CLK_TCK); system("pause"); return 0; }
2.精確計時方法
這里精確的含義是計時的精度更高,為了達到更高的計時精度,需要使用精確時間函數QueryPerformanceCounter()和QueryPerformanceFrequency(),它們需要計算機從硬件上支持精確定時器。當然,現在計算機一般都是支持的。
QueryPerformanceCounter()函數返回高精確度計數器的脈沖數目(計時數),QueryPerformanceFrequency()函數提供了高精度計時器的頻率值,即每秒脈沖數。
bool QueryPerformanceFrequency (LARGE_INTEGER *lpFrequency); bool QueryPerformanceCounter (LARGE_INTEGER *lpCount);
其中,數據類型LARGE_INTEGER既可以是一個8字節長的整型數,也可以是兩個4字節長的整型數的聯合結構, 其具體用法根據編譯器是否支持64位而定。該類型的定義如下:
typedef union _LARGE_INTEGER { struct { DWORD LowPart ;// 4字節整型數 LONG HighPart;// 4字節整型數 }; LONGLONG QuadPart ;// 8字節整型數 }LARGE_INTEGER ;
在進行定時之前,先調用QueryPerformanceFrequency()函數獲得機器內部定時器的時鍾頻率,然后在需要嚴格定時的事件發生之前和發生之后分別調用QueryPerformanceCounter()函數,利用兩次獲得的計數之差及時鍾頻率,計算出事件經歷的精確時間。其過程與clock()方法類似,但這里的時鍾頻率很高,測試電腦上頻率的QuadPart值為3118031,其精度原高於clocK()。
為了更好地使用這種計時方式,已將其封裝成HpTime類,下載。使用該類,計時程序如下
/* *作者:侯凱 *說明:HpTime類高精度計時 *日期:2013-6-6 */ #include "hptime.h" #include <iostream> using namespace std; int main() { long i = 10000000L; HpTime hpTime; while( i-- );//要計時的函數段 printf("The time was: %f\n", hpTime.sec()); system("pause"); return 0; }