前几天看到同学写matlab代码时,随手写上tic、toc就记录了时间,甚感震惊——居然计时函数可以如此简洁。
一般写 C 程序测速时,需要先记录起始时间,然后在结束时再次记录时间,并输出时间差。算起来要3行代码才能完成一个计时任务。一般用起来倒也不算麻烦,但是在寻找程序热点的时候,每几行代码就加入一段冗长的计时代码,会非常的碍眼。
在此诱惑之下,我写了一个简单的计时器,使用时只需在开始计时时写上“tic”,后面每个需要计时的节点写上“toc”,在需要的时候使用“tictoc(stdout);”就可以输出各部分的运行时间。输出的格式形如“line 12-15: 0.87”。
经过简单的预判断,程序可以支持 Windows 和 Linux,一般自己写点小程序够用了。
程序也有一些缺陷,比如只支持单文件,不能在并行的程序快内使用。另外如果需要获得更好的精度及效率,Windows 下应使用 QueryPerformanceCounter(),Linux 下应使用 clock_gettime(),替代 getTime() 的实现。
P.S. 如果想知道程序的热点,使用 Intel Amplifier 是一个很好的选择,可以看精确到行的耗时,也可以查看程序的并行程度,有针对性地提高性能。在官网上可以下载并免费申请一个月的试用 license。
代码如下,也可以访问 github 获取(https://github.com/licstar/util/blob/master/timer.h)。
#ifndef TIMER_H #define TIMER_H #ifdef __linux__ #include <sys/time.h> #else #include <time.h> #endif #include <stdio.h> double getTime(){ #ifdef __linux__ timeval tv; gettimeofday(&tv, 0); return tv.tv_sec + tv.tv_usec * 1e-6; #else return 1.0 * clock() / CLOCKS_PER_SEC; #endif } #define tic tic_f(__LINE__); #define toc toc_f(__LINE__); #define MAX_LINE 10000 double _timer[MAX_LINE] = {0}; int _fromLine[MAX_LINE] = {0}; int _lastLineNum = -1; double _lastRdtsc = 0; inline void tic_f(int line){ _lastLineNum = line; _lastRdtsc = getTime(); } inline void toc_f(int line){ double t = getTime(); _fromLine[line] = _lastLineNum; _timer[line] += t - _lastRdtsc; _lastLineNum = line; _lastRdtsc = t; } inline void tictoc(FILE *out){ int i; for(i = 0; i < MAX_LINE; i++){ if(_timer[i] != 0) fprintf(out, "line %d - %d: %.3f\n", _fromLine[i], i, _timer[i]); } fflush(out); } #endif
不错,学习了