日期:2014-05-16  浏览次数:20807 次

如何利用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=%Es\tUserTime=%Us\tSysTime=%Ss\tCPU=%P\nMemeryAvg=% Kkb\tDataAvg=%Dkb\tStackAvg=%kb\tSharedAvg=%Xkb\nResidentSetMax=%Mkb\tReside ntSetAvg=%tkb\tPageSize=%Zb\nMajorPageFault=%Ftims\tMinorPageFault=%Rtimes\t Swapped=%Wtimes\nContext-SwitchedInvoluntarily=%ctimes\tContext-SwitchedVolu ntarily=%wtimes\nFileSystemInput:%Itimes\tFileSystemOutput=%Otimes\nSocketMs gReceived=%rtimes\tSocketMsgSent=%stimes\nSignalsDelevered=%ktimes\t\tExitSt 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文件: