標籤:style class blog code http tar
轉載自:http://velep.com/archives/973.html
統計函數或某一段代碼的已耗用時間在軟體開發中常常遇到。透過已耗用時間可分析出函數或程式段的運行效率和效能,從而有針對性的對代碼進行最佳化。
在unix環境中,常常用binutils(GNU二進位工具集)中的gprof工具來查看函數已耗用時間。但本文的重點是自己編寫代碼實現函數或程式段已耗用時間的統計。下面進行詳細描述。
實現原理
實現原理很簡單,在函數或程式段開始運行前,記錄開始時間。運行完成後,記錄結束時間。把結束時間與開始時間相減,得到總的已耗用時間。
通常情況下,函數或程式段已耗用時間比較短暫,一般為us或ms層級。為得到比較準確的已耗用時間,通常做法是:重複N次運行函數或程式段,得到N次啟動並執行總時間T。單次已耗用時間 = T / N。N越大,得到的已耗用時間越準確。
現在的問題是如何擷取開始和和結束時間,而且時間的精度要達到us級。
gettimeofday()函數
gettimeofday()函數用於取得當前的時間,時間精度可達到us層級。
標頭檔:#include <sys/time.h>
函數原型:int gettimeofday(struct timeval * tv, struct timezone * tz);
函數說明:gettimeofday()函數會把目前的時間由tv所指的結構體返回,當地時區的資訊則放到tz所指的結構體中。
timeval結構體定義:
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
};
timezone結構體定義:
struct timezone {
int tz_minuteswest; /* 和Greenwich差了多少分鐘 */
int tz_dsttime; /* 日光節約時間的狀態 */
};
上述兩個結構體都定義在/usr/include/sys/time.h檔案中。tz_dsttime所代表的狀態如下:
DST_NONE:不使用
DST_USA:美國
DST_AUST:澳洲
DST_WET:西歐
DST_MET:中歐
DST_EET:東歐
DST_CAN:加拿大
DST_GB:大不列顛
DST_RUM:羅馬尼亞
DST_TUR:土耳其
DST_AUSTALT:澳洲(1986年以後)
函數傳回值:成功返回0,失敗返回-1,錯誤碼存於errno。
程式樣本
下面的代碼展示了如何使用gettimeofday()函數來統計函數或某一段代碼的已耗用時間。
/* * Test function run time. */ #include <stdio.h>#include <sys/time.h> void func(void){ double c = 2.5641321, d = 0.00158; double val = 0.0; for (int i = 0; i < 1000000; i++) { val += (c * c) + (d * d) + (2 * c * d); } return;} int main(int argc, char **argv){ struct timeval tpstart, tpend; float timeuse; gettimeofday(&tpstart, NULL); func(); gettimeofday(&tpend, NULL); timeuse = 1000000 * (tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec; timeuse /= 1000000; printf("Used Time: %f seconds\n", timeuse); return 0;}
這種方法,不僅適用於linux程式,也適用於eCos應用程式。