参考网址:https://gmbabar.wordpress.com/2010/12/01/mktime-slow-use-custom-function/
最近我正在做以ASCII(C字符串)格式表示的时间戳的工作。为了不同的计算,我经常需要转换时间戳字符串到epoch时间。标准C库提供mktime函数,它把已经填充的tm结构作为参数传递给mktime函数。如果你不非常频繁的使用该函数,它工作的很好。但是如果你需要在运行时转换数以万计的时间戳字符串,这个函数就变成应用程序的瓶颈。我没有尝试去阅读mktime的源代码和汇编代码,因此我不能确定为什么这个函数开销会这么大。但是我只是实现自己的自定义函数完成mktime做的转换。结果让我不敢相信。每个函数运行1M调用,结果如下:
mktime: 2950000 microseconds
time_to_epoch: 60000 microseconds
下面是自定义函数的源代码:
注:当时区为北京时间时,utcdiff设置为-8时才能得到UTC时间,即time(NULL)时间。
time_t time_to_epoch ( const struct tm*ltm, int utcdiff ) {
const int mon_days [] =
{31, 28, 31, 30, 31, 30,31, 31, 30, 31, 30, 31};
long tyears, tdays, leaps,utc_hrs;
int i;
tyears = ltm->tm_year –70 ; // tm->tm_year is from 1900.
leaps = (tyears + 2) / 4;// no of next two lines until year 2100.
//i = (ltm->tm_year –100) / 100;
//leaps -= ( (i/4)*3 + i%4);
tdays = 0;
for (i=0; i <ltm->tm_mon; i++) tdays += mon_days[i];
tdays += ltm->tm_mday-1;// days of month passed.
tdays = tdays + (tyears *365) + leaps;
utc_hrs = ltm->tm_hour +utcdiff; // for your time zone.
return (tdays * 86400) +(utc_hrs * 3600) + (ltm->tm_min * 60) + ltm->tm_sec;
}
void str_to_tm ( char *mdate, char *mtime, structtm* mtm ) {
char*pstr;
long year,month, day, hour, min, sec;
year =strtol( mdate, &pstr, 10 );
month =strtol( ++pstr, &pstr, 10 );
day =strtol( ++pstr, &pstr, 10 );
hour =strtol( mtime, &pstr, 10 ); while( !isdigit(*pstr) ) ++pstr;
min =strtol( pstr, &pstr, 10 ); while( !isdigit(*pstr) ) ++pstr;
sec =strtol( pstr, &pstr, 10 );
mtm->tm_sec = sec;
mtm->tm_min = min;
mtm->tm_hour = hour;
mtm->tm_mday = day;
mtm->tm_mon = month – 1;
mtm->tm_year = year – 1900;
}
int main ( int argc, char *argv[] ) {
charmydate[] = “2010-11-30”;
charmytime[] = “11:30:45”;
struct tmmtm;
time_tticks, mytcks;
str_to_tm( mydate, mytime, &mtm );
mytcks =time_to_epoch ( &mtm, 5 );
ticks = mktime( &mtm );
printf ( ”std func time : %s”, asctime( localtime( &ticks ) ) );
printf ( ”our func time : %s”, asctime( localtime( &mytcks ) ) );
printf ( ”stdlib func ticks : %ld \n”, ticks );
printf ( ”our func ticks : %ld \n”, mytcks );
}
输出如下:
std func time : Tue Nov 30 11:30:45 2010
our func time : Tue Nov 30 11:30:45 2010
std func ticks : 1291134645
our func ticks : 1291134645