统计函数或某一段代码的运行时间在软件开发中常常遇到。透过运行时间可分析出函数或程序段的运行效率和性能,从而有针对性的对代码进行优化。
在unix环境中,常常用binutils(GNU二进制工具集)中的gprof工具来查看函数运行时间。但本文的重点是自己编写代码实现函数或程序段运行时间的统计。下面进行详细描述。
实现原理
实现原理很简单,在函数或程序段开始运行前,记录开始时间。运行完成后,记录结束时间。把结束时间与开始时间相减,得到总的运行时间。
通常情况下,函数或程序段运行时间比较短暂,一般为us或ms级别。为得到比较准确的运行时间,通常做法是:重复N次运行函数或程序段,得到N次运行的总时间T。单次运行时间 = T / N。N越大,得到的运行时间越准确。
现在的问题是如何获取开始和和结束时间,而且时间的精度要达到us级。
gettimeofday()函数
gettimeofday()函数用于取得当前的时间,时间精度可达到us级别。
头文件:#include <sys/time.h>
函数原型:int gettimeofday(struct timeval * tv, struct timezone * tz);
函数说明:gettimeofday()函数会把目前的时间由tv所指的结构体返回,当地时区的信息则放到tz所指的结构体中。
timeval结构体定义:
struct timeval { time_t tv_sec; suseconds_t tv_usec; };
timezone结构体定义:
struct timezone { int tz_minuteswest; /* 和Greenwich差了多少分钟 */ int tz_dsttime; /* 日光节约时间的状态 */ };
上述两个结构体都定义在/usr/include/sys/time.h文件中。tz_dsttime所代表的状态如下:
- DST_NONE:不使用
- DST_USA:美国
- DST_AUST:澳洲
- DST_WET:西欧
- DST_MET:中欧
- DST_EET:东欧
- DST_CAN:加拿大
- DST_GB:大不列颠
- DST_RUM:罗马尼亚
- DST_TUR:土耳其
- DST_AUSTALT:澳洲(1986年以后)
函数返回值:成功返回0,失败返回-1,错误码存于errno。
程序示例
下面的代码展示了如何使用gettimeofday()函数来统计函数或某一段代码的运行时间。
/* * Test function run time. */ #include <stdio.h> #include <sys/time.h> void func(void) { double c = 2.5641321, d = 0.00158; double val = 0.0; for (int i = 0; i < 1000000; i++) { val += (c * c) + (d * d) + (2 * c * d); } return; } int main(int argc, char **argv) { struct timeval tpstart, tpend; float timeuse; gettimeofday(&tpstart, NULL); func(); gettimeofday(&tpend, NULL); timeuse = 1000000 * (tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec; timeuse /= 1000000; printf("Used Time: %f seconds\n", timeuse); return 0; }
这种方法,不仅适用于linux程序,也适用于eCos应用程序。
推荐阅读相关文章:
- terminate called after throwing an instance of ‘std::length_error’ what(): basic_string::_S_create
- 编译错误:error: stray ‘\357’ in program
- linux backtrace()详细使用说明,分析Segmentation fault
- linux性能分析工具oprofile的安装与使用
- likely(x)与unlikely(x)函数,即__builtin_expect的使用
- 干掉你程序中的僵尸代码
- Linux平台下如何检测、调试C/C++程序内存泄漏?
- ymodem源码(基于C语言实现)