背景
最近在重新編譯ijkplayer,并且希望能夠打印出來(lái)各個(gè)階段的時(shí)間,以便對(duì)于ijkplayer進(jìn)一步調(diào)優(yōu)
獲取時(shí)間
Linux獲取時(shí)間有多種方案,都需要添加#include <time.h>
- time調(diào)用
通過(guò)time函數(shù)獲得當(dāng)前時(shí)間,注意單位為秒,其中time_t結(jié)構(gòu)體是一個(gè)有符號(hào)的長(zhǎng)整型。
而ctime是一個(gè)返回格式化好的字符串的指針。格式為Thu Nov 24 18:22:48 1986\n\0
#include <time.h>
int main()
{
time_t timep;
time (&timep);
printf(“%s”,ctime(&timep));
return 0;
}
- gettimeofday調(diào)用
通過(guò)gettimeofday調(diào)用返回來(lái)的是一個(gè)timeval的結(jié)構(gòu)體,其中tv_sec是秒數(shù),tv_usec是微秒數(shù),通過(guò)這兩個(gè)數(shù)共同標(biāo)志當(dāng)前時(shí)間
#ifndef _STRUCT_TIMEVAL
#define _STRUCT_TIMEVAL struct timeval
_STRUCT_TIMEVAL
{
__darwin_time_t tv_sec; /* seconds */
__darwin_suseconds_t tv_usec; /* and microseconds */
};
#endif /* _STRUCT_TIMEVAL */
該函數(shù)的使用如下
#include <sys/time.h>
int main(void)
{
struct timeval time;
gettimeofday(&time, NULL);
printf("Current Time Seconds: %ld,uSeconds:%ld\n", time.tv_sec,time.tv_usec);
return 0;
}
注意
因?yàn)樵谑謾C(jī)上測(cè)試的時(shí)候,通過(guò)gettimeofday獲取時(shí)間,并且通過(guò)網(wǎng)上t.tv_sec*1000+t.tv_usec/1000來(lái)計(jì)算毫秒數(shù),結(jié)果得到的時(shí)間錯(cuò)誤。而原因就是32位的系統(tǒng)上,long占四個(gè)字節(jié),超出2^32則會(huì)溢出,導(dǎo)致結(jié)果錯(cuò)誤。
比如,當(dāng)前通過(guò)gettimeofday獲取到的t.tv_sec為1534132538,而t.tv_sec*1000的結(jié)果為8292133328。
原因是:
1534132538的二進(jìn)制為:
1011011011100010000000100111010
1534132538000的二進(jìn)制為:
10110010100110001011011001100101010010000
而在32位的機(jī)器上,long最多占用32,所以得到的32位二進(jìn)制如下:
00110001011011001100101010010000
轉(zhuǎn)成10進(jìn)制就是:
829213328
所以,64位的CPU可以進(jìn)行該運(yùn)算,32位的會(huì)因?yàn)橐绯鰧?dǎo)致值不對(duì)
最終的解決方案是,通過(guò)long long類型的數(shù)據(jù)結(jié)構(gòu)來(lái)保存,long long 占8個(gè)字節(jié),也就是最大值為2^64:
long long gettime(){
struct timeval tv;
gettimeofday(&tv,NULL);
long long seconds=tv.tv_sec; // 先將tv.tv_sec保存成long long類型
return seconds*1000+tv.tv_usec/1000;
}