时间与计时

在写运行日志时,一般会将当前时间与日志内容一并写入文件,方便分析故障;另外在程序性能调优时,准确得知接口或函数的执行时间可方便地定位程序瓶颈在哪里,对优化方向有重要的指导意义。

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;
}
#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;
}
Table of Contents