用clock()函數計時的坑

程序中常常用time()函數來返回當前系統時間的秒數,來計時或計算時間差。若是須要用到更高精度的時間,就會天然想到用clock()函數。想固然的認爲它返回從程序開始tick數,用clock()/CLOCKS_PER_SEC就能獲得以秒計數的時間了。然而結果不是這樣,看下面的程序log。一行開頭是系統時間,後面是clock()算出來的,明顯比系統時間要慢很多。服務器

2019-03-06 17:47:55.865 16213-18332/ E/jniUtil-jni: cur_time 3.399163
2019-03-06 17:47:56.273 16213-18332/ E/jniUtil-jni: cur_time 3.671865
2019-03-06 17:47:56.722 16213-18332/ E/jniUtil-jni: cur_time 4.006435
2019-03-06 17:47:57.113 16213-18332/ E/jniUtil-jni: cur_time 4.277441
2019-03-06 17:47:57.527 16213-18332/ E/jniUtil-jni: cur_time 4.540576
2019-03-06 17:47:57.928 16213-18332/ E/jniUtil-jni: cur_time 4.775973
2019-03-06 17:47:58.269 16213-18332/ E/jniUtil-jni: cur_time 4.925488
2019-03-06 17:47:58.394 16213-18332/ E/jniUtil-jni: cur_time 4.989181
2019-03-06 17:47:58.488 16213-18332/ E/jniUtil-jni: cur_time 5.023780
2019-03-06 17:47:58.911 16213-18332/ E/jniUtil-jni: cur_time 5.222049
2019-03-06 17:47:59.480 16213-18332/ E/jniUtil-jni: cur_time 5.476535
2019-03-06 17:47:59.980 16213-18332/ E/jniUtil-jni: cur_time 5.724581
2019-03-06 17:48:00.551 16213-18332/ E/jniUtil-jni: cur_time 5.995964
2019-03-06 17:48:00.965 16213-18332/ E/jniUtil-jni: cur_time 6.183607函數

緣由是clock()計算的是從程序運行開始被程序進程使用的CPU時間tick,而不是真正現實世界流逝的時間。很顯然這個時間確定要比現實時間要慢的多,除非CPU只有你這麼一個進程在跑,佔用了所有CPU。因此若是你要benchmark一段代碼,看看運行這段代碼花費了多少時間,用clock()很合適。那麼要比較精確地計算現實流逝地時間,怎麼辦呢?用clock_gettime()。spa

extern int clock_gettime(clockid_t, struct timespec*);

struct timespec {
 __kernel_time_t tv_sec;
 long tv_nsec;
};

第一個參數clockid_t類型常見的有四種:   線程

CLOCK_REALTIME:系統實時時間。
CLOCK_MONOTONIC:從系統啓動時開始計時,不受系統時間被用戶改變的影響。
CLOCK_PROCESS_CPUTIME_ID:本進程到當前代碼系統CPU花費的時間,包含該進程下的全部線程。
CLOCK_THREAD_CPUTIME_ID:本線程到當前代碼系統CPU花費的時間。code

能夠看到,若是用CLOCK_PROCESS_CPUTIME_ID,就和直接用clock()是同樣的。而要計算現實時間,就不能用後兩種類型,必須用CLOCK_REALTIME或者CLOCK_MONOTONIC。要計算時間差,秒對秒一減,納秒對納秒一減,統一到同一個單位相加便可。blog

除了上面四種clockid_t類型,還有幾種。進程

CLOCK_REALTIME_COARSE,CLOCK_MONOTONIC_COARSE:帶COARSE後綴的,精度沒有不帶後綴的高,可是速度快。get

CLOCK_MONOTONIC_RAW:和CLOCK_MONOTONIC相似,可是它是訪問的硬件時間,不受NTP時間服務器的調整和adjtime()的影響。class

CLOCK_BOOTTIME:和CLOCK_MONOTONIC同樣,可是包含系統掛起的時間。硬件

相關文章
相關標籤/搜索