关于时间的文章可以参考我之前的文章《C语言操作时间函数,实现定时执行某个任务小程序》0。问题描述爱好者们想计算一个函数的执行时间。1、问题分析函数执行时间的统计在嵌入式系统中会经常用到,知识点很重要。本文从两个方面讨论类似的问题:计算程序中一个函数的执行时间计算一个程序的执行时间2.如何计算程序中一个函数的执行时间?1.思路我们记录函数执行前后的时间戳,然后计算两个时间戳的差值。我们需要使用函数clock_gettime来实现这个功能。看这个函数的定义:#includeintclock_gettime(clockid_tclk_id,structtimespec*tp);可以根据需要获取不同需求的准确时间参数:clk_id:获取并设置的clk_id指定的时钟时间。CLOCK_REALTIME:系统实时时间,随着系统实时时间的变化而变化,即从UTC1970-1-10:0:0开始计时,如果系统时间被用户更改为其他时间CLOCK_MONOTONIC:从系统启动从此时开始计时,不受用户更改系统时间的影响:本线程到当前码制CPU耗时tp:得到的时间戳会存放在这个结构体变量中,structtimespec{time_ttv_sec;/*second*/longtv_nsec;/*nanosecond*/};返回值:success0failure-1,并且errno会被赋值,因为我们要计算执行某个函数的时间,所以我们第一个参数选择CLOCK_MONOTONIC。2、例1先来实现一个简单的程序:1#include2#include3#include4#include5#include6#include7#include8#include9#include1011intmain()12{13intrc;14structtimespects_start,ts_end;1516//starttimebeforecallfunction17rc=clock_gettime(CLOCK_MONOTONIC,&ts_start);1819printf("youcancallyyourfunctionhere\n");2021//endtimebeforecallfunction22rc=clock_gettime(CLOCK_MONOTONIC,&ts_end);2324printf("CLOCK_MONOTONIReports%ld.%09ldts_seconds\n",ts_start.tv_sec,ts_end.tv_nsec-ts_start.tv_nsec);26}Line19我们可以把我们要执行的函数放在这里。编译gccruntime.c-lrt注意需要添加动态链接库lrt,库中定义了函数clock_gettime()。执行结果如下:root@ubuntu:/home/peng/zhh#./a.outyoucancallyourfunctionhereCLOCK_MONOTONIReports0.000013689seconds3。例2——一个比较完美的例子第一个例子比较简单,在实践中,尤其是在网络通信中,经常需要计算发送和接收数据包的总时间,以网络的速率计算。现在我们添加如下功能:检查执行该功能前后时间戳的有效性,因为有时候记录时间会比较长,会出现数据溢出等问题。总执行时间会在一个循环中累加,计算总执行时间,根据执行次数计算平均执行时间。timea)检查时间有效性timespec_check()staticinttimespec_check(structtimespec*t){if((t->tv_nsec<0)||(t->tv_nsec>=1000000000))return-1;return0;}功能:本函数校验时间戳成员tv_nsec,取值不能小于0,不能大于1000000000参数:ttimestamp返回值成功返回0非法返回-1timespec_sub()staticvoidtimespec_sub(structtimespec*t1,structtimespec*t2){if(timespec_check(t1)<0){fprintf(stderr,"invalidtime#1:%lld.%.9ld.\n",(longlong)t1->tv_sec,t1->tv_nsec);return;}if(timespec_check(t2)<0){fprintf(stderr,"invalidtime#2:%lld.%.9ld.\n",(longlong)t2->tv_sec,t2->tv_nsec);返回;}t1->tv_sec-=t2->tv_sec;t1->tv_nsec-=t2->tv_nsec;if(t1->tv_nsec>=1000000000){//tv_nsec超过1000000000,需要加上1t1->tv_sec++;t1->tv_nsec-=1000000000;}elseif(t1->tv_nsec<0){//tv_nsec小于0,秒需要减去1t1->tv_sec--;t1->tv_nsec+=1000000000;}}功能:该函数首先校验有效性参数t1和t2,然后t1时间减去t2,结果存入t1参数:t1:相应函数执行结束的时间t2:对应函数执行前的时间返回值:无b)实现1#include2#include3#include4#include5#include6#include7#include8#include9#include101112staticinttimespec_check(structtimespec*t)13{14if((t->tv_nsec<0)||(t->tv_nsec>=1000000000))15return-1;1617return0;18}1920staticvoidtimespec_sub(structtimespec*t1,structtimespec*t2)21{22if(timespec_check(t1)<0){23fprintf(stderr,"invalidtime#1:%lld.%.9ld.\n",24(longlong)t1->tv_sec,t1->tv_nsec);25return;26}27if(timespec_check(t2)<0){28fprintf(stderr,"invalidtime#2:%lld.%.9ld.\n",29(longlong)t2->tv_sec,t2->tv_nsec);30return;31}3233t1->tv_sec-=t2->tv_sec;34t1->tv_nsec-=t2->tv_nsec;35if(t1->tv_nsec>=1000000000)36{37t1->tv_sec++;38t1->tv_nsec-=1000000000;39}40elseif(t1->tv_nsec<0)41{42t1->tv_sec--;43t1->tv_nsec+=1000000000;44}45}4647intmain()48{49intrc;50intcount=10;51longt_time_n=0;//nanosecend52longt_time_s=0;//secnd53structtimespects_start,ts_end;545556while(count--){5758us=clock_gettime(CLOCK_MONOTS_start)IC,&9(200);6061rc=clock_gettime(CLOCK_MONOTONIC,&ts_end);6263timespec_sub(&ts_end,&ts_start);64t_time_n+=ts_end.tv_nsec;65t_time_s+=ts_end.tv_sec;6667#if068printf("CLOCK_MONOTONIReports"%lds.\s_endsec.ld_second);70#endif71}72printf("**Totaltime%lds+%ldnsec\n",t_time_s,t_time_n);73}编译执行如下:root@ubuntu:/home/peng/zhh#./a.out**Totaltime0s+9636103nsec3.计算程序的执行时间有时候我们想知道执行某个程序需要多长时间。我们可以使用命令time1。命令timeLinux时间的目的是衡量执行特定命令所需消耗的时间和系统资源等信息。CPU资源的统计包括实时、消耗在用户态的进程、消耗在内核态的进程。2.语法time[options]COMMAND[arguments]3.例子11.root@ubuntu:/home/peng/zhh#timedate2.TueFeb2303:44:27PST20213.4.real0m0.001s5.user0m0.000s6.sys0m0.000s以上在例如,执行命令“timedate”(见第1行)。系统首先执行命令“date”,第二行是命令“date”的执行结果。第3-6行是执行命令“date”的时间统计结果,其中第四行“real”为实际时间,第五行“user”为用户CPU时间,第六行“sys”为系统CPU时间。以上三种时间显示格式均为MMmNN[.FFF]s。4、在例2中,我们还可以测试上一章我们写的程序:root@ubuntu:/home/peng/zhh#time./a.out**Totaltime0s+9649603nsec,avg_time=-9649603.000000real0m0.010suser0m0。000ssys0m0.000s接下来我们将59行代码中的usleep(200)改为sleep(1),重新编译执行。10秒后,会打印出如下执行结果:root@ubuntu:/home/peng/zhh#time./a.out**Totaltime10s+8178015nsecreal0m10.009suser0m0.000ssys0m0.000s的结果与预期基本一致。你可以根据我的代码很方便的把这个功能移植到你自己的项目中。