时间与计时
在写运行日志时,一般会将当前时间与日志内容一并写入文件,方便分析故障;另外在程序性能调优时,准确得知接口或函数的执行时间可方便地定位程序瓶颈在哪里,对优化方向有重要的指导意义。
C库函数计时
可通过clock()函数来实现,函数原型为:clock_t clock(void);
,它返回进程启动到调用函数时所经过的CPU时钟计时单元数(returns the processor time consumed by the program),将它除以CLOCKS_PER_SEC将得到对应的秒数。
#include <stdio.h>
#include <time.h>
int main() {
clock_t t1, t2;
t1 = clock();
// do something here
t2 = clock();
printf("cost time: %zd ms\n", (t2 - t1) * 1000 / CLOCKS_PER_SEC);
return 0;
}
对于简单的程序而言,clock()可以满足要求,但如果环境比较复杂,可考虑用time()函数,它将获得从1970年1月1日0点0分0秒到当前时刻的秒数,原型为:time_t time(time_t *tm)
,如果参数不为NULL,则额外将秒数赋给指针所指的time_t变量。
#include <stdio.h>
#include <time.h>
int main() {
time_t t1, t2;
time(&t1);
// do something here
time(&t2);
printf("cost time: %zd s\n", t2 - t1);
return 0;
}
该方法的缺陷是只能精确到秒,对于Windows客户端环境基本也够用,在Linux下通过gettimeofday()函数可获得微秒级精度的时间,函数原型为:int gettimeofday(struct timeval *tv, void *tzp);
。
#include <stdio.h>
#include <sys/time.h>
int main() {
struct timeval t1, t2;
gettimeofday(&t1, NULL);
// do something here
gettimeofday(&t2, NULL);
printf("cost time: %zd ms\n", (t2.tv_sec * 1000000 + t2.tv_usec
- t1.tv_sec * 1000000 - t1.tv_usec) / 1000);
return 0;
}
在写日志时,为了方便阅读,可通过localtime()函数将秒数转换成时间,然后可用strftime()函数转成想要的格式,函数原型如下:
size_t strftime(char *buf, size_t size, const char *fmt, const struct tm *tm);
struct tm* localtime(const time_t *t);
这两函数都是C库函数,移植性好,以下是个例子。
#include <stdio.h>
#include <time.h>
int main() {
char timestr[64];
time_t t = time(NULL);
struct tm *tm = localtime(&t);
strftime(timestr, sizeof(timestr), "%y-%m-%d %H:%M:%S", tm);
puts(timestr);
return 0;
}
- Linux环境,精确到毫秒/微秒
#include <stdio.h>
#include <sys/time.h>
int main() {
char timestr[64];
struct tm *tm;
struct timeval tv;
gettimeofday(&tv, NULL);
tm = localtime(&tv.tv_sec);
sprintf(timestr, "%02d-%02d-%02d %02d:%02d:%02d.%03d",
tm->tm_year - 100, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec / 1000);
puts(timestr);
return 0;
}