当前位置:  技术问答>linux和unix

如何利用time命令对程序进行全面统计——原创

    来源: 互联网  发布时间:2017-01-24

    本文导语:  简单说一下起因,前两天做ACM的时候总是超时,所以就想自己测试一下程序的执行效率,就想到了time命令,然后又无意间发现fedora的time命令和freebsd的time命令不太一样,freebsd的time命令有更全面的内容,比如驻留集大...

简单说一下起因,前两天做ACM的时候总是超时,所以就想自己测试一下程序的执行效率,就想到了time命令,然后又无意间发现fedora的time命令和freebsd的time命令不太一样,freebsd的time命令有更全面的内容,比如驻留集大小,IO次数等等,于是我就想fedora能不能也做到这一点,就来csdn上问,竟没人回答,最终还是自己解决了这个问题,有个朋友发帖让我详细分享一下,于是乎我就把详细过程以及一些必要的资料分享一下:
1、linux原始的time命令是这样的:
real 0m0.000s(实际运行时间)
user 0m0.000s(用户态时间——相当于level3时间)
sys 0m0.000s(核心态时间——相当于level0时间)
它只显示了3个时间,但实际上它隐藏了cpu使用率这么一个数据没有显示,如果你想显示这个数据,可以通过建立TIMEFORMAT变量来指定time的显示格式,以下是我定义的格式:
export TIMEFORMAT=$'nRealTime=%3lR  UserTime=%3lU  SysTime=%3lS  CPU=%P%%'
显示:
RealTime=0m0.019s  UserTime=0m0.006s  SysTime=0m0.014s  CPU=103.35%
(顺便说一下,cpu使用率就是UserTime+SysTime/RealTime的比值,如果你的电脑是多核心的话,这个值有可能超过100%)
(如果你对系统自带time的需求已经满足的话,那么下面的内容可以忽略)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2、如何让time统计更多的数据?
这4项内容已经是fedora自带的time命令的全部功能了,如果想统计更多的数据,就需要新的工具,叫做GNU time 1.7,是gun自己开发的time命令,反正fedora不自带这个命令,其他linux系统有没有我不知道,它的下载地址是:
http://ftp.gnu.org/gnu/time/
拿到源码,编译安装就可以了,不过问题时fedora自带的time命令是/usr/bin/time,自己安装的time1.7是/usr/local/bin/time(默认),两个time重名,而且奇怪的是/usr/bin/time无法删除,删除完以后又自动生成,也没法替换,替换完还是原来的time命令,表示非常不解,请高手指点……
没办法,只能给自己装的time改名成time1.7,然后用alias直接屏蔽掉系统自带的time,当然你也可以不屏蔽,换一个其他的名字,让两个命令共用……
具体的设置参考:http://linux.about.com/library/cmd/blcmdl1_time.htm
或者中文版:http://www.360doc.com/content/11/1108/08/1671317_162679287.shtml
其实网上资料很多的,我当时参考的是上面的两个……
然后大家可以time -v ps 查看一下功能:
Command being timed: "ps"
User time (seconds): 0.00
System time (seconds): 0.02
Percent of CPU this job got: 92%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.02
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 3616
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 272
Voluntary context switches: 1
Involuntary context switches: 4
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
相当给力哈,基本上你想知道的内容都统计在这里了,具体的含义,可以参照上面给的两个网址,里面有详细的介绍,其实安装完以后,有一个info文件,还有什么比官方的info更全面的呢?

但是由于系统提供的-v参数是纵向打印,会把程序自身的打印结果刷掉,所以我自定义了一下新time的格式:
export TIME=$'nRealTime=%EstUserTime=%UstSysTime=%SstCPU=%PnMemeryAvg=%    KkbtDataAvg=%DkbtStackAvg=%kbtSharedAvg=%XkbnResidentSetMax=%MkbtReside    ntSetAvg=%tkbtPageSize=%ZbnMajorPageFault=%FtimstMinorPageFault=%Rtimest    Swapped=%WtimesnContext-SwitchedInvoluntarily=%ctimestContext-SwitchedVolu    ntarily=%wtimesnFileSystemInput:%ItimestFileSystemOutput=%OtimesnSocketMs    gReceived=%rtimestSocketMsgSent=%stimesnSignalsDelevered=%ktimesttExitSt    atusOfCommand=%x'
懒得自己写格式的同学,可以cp下去直接用……
注意,新的time命令默认使用的变量时TIME而不再是TIMEFORMAT了,这其实为我们同时使用两个time命令提供了便利,看一下格式化后的结果:
RealTime=0:00.01s UserTime=0.00s SysTime=0.01s CPU=89%
MemeryAvg=0kb DataAvg=0kb StackAvg=0b SharedAvg=0kb
ResidentSetMax=3616kb ResidentSetAvg=0kb PageSize=4096b
MajorPageFault=0tims MinorPageFault=270times Swapped=0times
Context-SwitchedInvoluntarily=3times Context-SwitchedVoluntarily=1times
FileSystemInput:0times FileSystemOutput=0times
SocketMsgReceived=0times SocketMsgSent=0times
SignalsDelevered=0times ExitStatusOfCommand=0
短了很多,对吧,目的达到了……
(至此,time的替换工作基本完成,不过这个time的提供的时间只能精确到10ms,不想系统自带的time可以精确到1ms,如果你已经满足于这个结果,那么下面的内容可以忽略,因为下面我们要去修改源代码)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3、让time的时间更精确
其实修改源代码的过程极度简单,所以如果你有兴趣,可以尝试修改一下,毕竟精度少一位总让人感觉非常的难受……
打开time-1.7目录(也就是刚才编译时的那个目录),打开time.c文件:
376行:fprintf (fp, "%ld:%02ld.%02ld", /* -> m:s.  */
改为:fprintf (fp, "%ld:%02ld.%03ld", /* -> m:s.  */(把最后一个2变成3即可)

379行:resp->elapsed.tv_usec / 10000);
改为:resp->elapsed.tv_usec / 1000);(删除一个0即可)

411行:fprintf (fp, "%ld.%02ld",
改为:fprintf (fp, "%ld.%03ld",(同样,把最后一个2变成3即可)

413行:resp->ru.ru_stime.TV_MSEC / 10);
改为:resp->ru.ru_stime.TV_MSEC);(把“/10”删掉)

416行:fprintf (fp, "%ld.%02ld",
改为:fprintf (fp, "%ld.%03ld",(还是一样,把最后一个2变成3即可)

418行:resp->ru.ru_utime.TV_MSEC / 10);
改为:resp->ru.ru_utime.TV_MSEC);(和413行的方法完全一样,删掉“/10”)

OK~

然后重新编译,重复一遍上面的工作,新的time命令就完成了,非常简单是吧,其实有编程经验的人一眼就能看出来,我只不过是在打印的时候,提高了1位精度而已,因为计时已经达到了微秒级的精度,但只显示10ms级的精度,所以其实精度的提升空间还很大的,有兴趣的同学可以进一步修改,时间完全可以达到us级别,只是我觉得ms对我就够用了,所以就没再去改……

再来看看新的命令吧:

Command being timed: "ps"
User time (seconds): 0.002
System time (seconds): 0.026
Percent of CPU this job got: 93%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.030
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 3632
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 273
Voluntary context switches: 1
Involuntary context switches: 8
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
看到没?精度已经提升为ms级别了……
(没啦,没啦,下面就是结束语啦!)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

至此,time的更新换代工作就全部完成了,我们可以得到的统计数据变得好多哈……
这为我们调试和测试程序提供了很大的便利……
谁说linux下没有好的测试软件,gdb+time+script就是相当NB的测试三件套,你完全可以通过驻留集的大小来判断是否有内存泄漏,通过IO次数的统计判断外排序的效率如何,总之,time只是提供了工具,怎么用这些工具,就全凭大家的想象力了……
不过值得强调的一点就是,time并不是专业的测试工具,它只是进行简单的整体统计,而且这个统计的过程会对程序的执行产生一些微小的影响,所以这个数据只能作为一种参考,协助你完善你的程序,最终的结果还是需要专业的测试环境以及实际投入使用时的运行结果来衡量……

|
故障,散花!
gdb+time已经很利器了!

|
再加上gprof+strace,功德圆满。

    
 
 

您可能感兴趣的文章:

  • linux下利用(cat,strings,head,sed)命令生成随机字符串
  • 利用 mount 函数 如何 挂载 ntfs 分区,如何调用(不是命令,是 MOUNT 函数)
  • 什么命令察看网卡的利用率?
  • 高手,我装了Cygwin,有153M,不知道装全了没有,我在命令行敲入gcc,不行,那我该怎么办,才能利用它进行编程?
  • 利用管道实现sudo命令免输入密码的方法
  • 如何利用read命令按行读取一个文件
  • 利用shell命令取得当前系统所有的IPC信息
  • 利用fork 与 dup2 执行 系统命令, 别的命令都可以获取执行结果,就fdisk 命令不可以. execve("/sbin/fdisk",args,NULL) , args 命令参数.
  • SQL Server利用bcp命令把SQL语句结果生成文本文件
  • 利用linux命令cat, uniq, sort找出file1中存在,file2中不存在的文本行
  • 请教:linux下有统计CPU的个数和CPU利用率的函数吗???(急!!!)
  • 解析如何利用switch语句进行字符统计
  • java利用mybatis拦截器统计sql执行时间示例
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • linux c下利用srand和rand函数生成随机字符串
  • 请问:Linux下用C编程计算CPU利用率和内存利用率?
  • Web前端开发如何利用css样式来控制Html中的h1/h2/h3标签不换行
  • Web服务器/前端 iis7站长之家
  • 如何利用libpcap和Python嗅探数据包
  • 大虾 紧急求助!!!!如何求得当前机子的处理器利用率和内存利用率?
  • windows堆栈溢出利用的七种方式
  • 如何利用Bash脚本(利用awksedgrepwc等)来自动修改配置文件
  • 求RADIUS的动态分配IP的问题(利用IPPOOL)
  • iowait和cpu利用率的权衡问题
  • 利用java.net.URLConnection上传文件
  • Qt中利用槽如何来传递参数
  • 浏览器漏洞利用框架 BeEF
  • 怎么样利用Socket进行Java网络编程
  • 请问如何编程获得CPU利用率?(空)
  • 如何利用Linux安装盘制作启动盘?
  • 谁知道linux/unix下利用Schema读取校验xml的开源代码,给一个链接,谢谢!
  • 怎样实现利用fprintf,输出定长字串,位数不足时在左侧填入指定字符填充。。
  • CPU、内存、数据库利用率监控
  • 怎样利用u-boot烧写??
  • 根目录 / 文件利用过高, 啥办法?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3