Answers:
首先根据乔恩·林的建议使用时间:
$ time ls test
test
real 0m0.004s
user 0m0.002s
sys 0m0.002s
您没有说脚本正在运行什么unix,而是在Linux上运行strace,在Solaris / AIX上运行truss,我认为hp-ux上的tusc可以使您了解很多有关进程正在执行的操作。我喜欢strace的-c选项来获得一个不错的摘要:
]$ strace -c ls
test
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
89.19 0.000998 998 1 execve
10.81 0.000121 121 1 write
0.00 0.000000 0 12 read
0.00 0.000000 0 93 79 open
0.00 0.000000 0 16 close
0.00 0.000000 0 2 1 access
0.00 0.000000 0 3 brk
0.00 0.000000 0 2 ioctl
0.00 0.000000 0 4 munmap
0.00 0.000000 0 1 uname
0.00 0.000000 0 6 mprotect
0.00 0.000000 0 2 rt_sigaction
0.00 0.000000 0 1 rt_sigprocmask
0.00 0.000000 0 1 getrlimit
0.00 0.000000 0 30 mmap2
0.00 0.000000 0 8 7 stat64
0.00 0.000000 0 13 fstat64
0.00 0.000000 0 2 getdents64
0.00 0.000000 0 1 fcntl64
0.00 0.000000 0 1 futex
0.00 0.000000 0 1 set_thread_area
0.00 0.000000 0 1 set_tid_address
0.00 0.000000 0 1 set_robust_list
0.00 0.000000 0 1 socket
0.00 0.000000 0 1 1 connect
------ ----------- ----------- --------- --------- ----------------
100.00 0.001119 205 88 total
另请注意,附加这些跟踪类型的程序可能会使程序变慢。
这不是完全概要分析,但是您可以在脚本运行时对其进行跟踪。将set -xv
您要跟踪的部分之前和set +xv
之后。set -x
启用xtrace,它将显示执行的每一行。set -v
启用详细模式,该模式还将显示可能有效但未执行的行,例如变量分配。
您还可以为跟踪添加时间戳。您需要一个可以对每行加盖时间戳的终端仿真器。我知道的唯一一个是RealTerm,它是Windows程序,但是可以与Wine一起使用。您也许也可以使用grabserial
,尽管除了真正的串行端口外,我还没有尝试过。您可以通过运行来找出外壳使用的串行设备ps -p $$
(如果没有,请使用man
找出如何在ps
输出中包括TTY列)。
另外,请参阅Stack Overflow上针对Shell脚本的性能分析工具。
time
几次迭代通过多次运行同一命令进行性能分析
time (for ((n=0;n<10;n++)); do echo "scale=1000; 4*a(1)" | bc -l; done)
where echo "scale=1000; 4*a(1)" | bc -l
计算pi并time (...)
确保for
循环作为单个命令运行。
自从我到这里结束了至少两次之后,我实现了一个解决方案:
https://github.com/walles/shellprof
它运行您的脚本,透明地计时所有打印的行,最后显示屏幕上最长的行的前10个列表:
~/s/shellprof (master|✔) $ ./shellprof ./testcase.sh
quick
slow
quick
Timings for printed lines:
1.01s: slow
0.00s: <<<PROGRAM START>>>
0.00s: quick
0.00s: quick
~/s/shellprof (master|✔) $