在shell中获取程序执行时间
我想在几个不同的条件下在linux shell中执行一些东西,并且能够输出每个执行的执行时间。
我知道我可以写一个perl或python脚本来做到这一点,但有没有办法在shell中做到这一点? (这恰好是bash)
使用内置time
关键字:
$帮助时间 时间:time [-p] PIPELINE 执行PIPELINE并打印实时,用户CPU时间, 以及在终止时执行PIPELINE所花费的系统CPU时间。 退货状态是PIPELINE的退货状态。 `-p'选项 以稍微不同的格式打印时间摘要。 这用途 TIMEFORMATvariables的值作为输出格式。
例:
$ time sleep 2
实际0m2.009s 用户0m0.000s sys 0m0.004s
您可以使用时间(1)获得比bash内置time
(Robert Gamble提到的)更详细的信息。 通常这是/usr/bin/time
。
编者按:为了确保你正在调用外部工具 time
而不是你的shell的time
关键字 ,请将其作为/usr/bin/time
调用。
time
是一个POSIX授权的工具 ,但是它唯一需要支持的选项是-p
。
特定的平台实现特定的非标准扩展: -v
与GNU的time
工具一起工作,如下所示(问题标记为linux ); BSD / macOS实现使用-l
来产生类似的输出 – 见man 1 time
。
详细输出示例:
$ /usr/bin/time -v sleep 1 Command being timed: "sleep 1" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 1% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05 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): 0 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 210 Voluntary context switches: 2 Involuntary context switches: 1 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
$ /usr/bin/time -v sleep 1 Command being timed: "sleep 1" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 1% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05 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): 0 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 210 Voluntary context switches: 2 Involuntary context switches: 1 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
#!/bin/bash START=$(date +%s) # do something # start your script work here ls -R /etc > /tmp/x rm -f /tmp/x # your logic ends here END=$(date +%s) DIFF=$(( $END - $START )) echo "It took $DIFF seconds"
对于逐行增量测量,请尝试gnonom 。
一个命令行工具,有点像moreutils的ts,把时间戳信息join到另一个命令的标准输出中。 对于长时间运行的stream程非常有用,在这个stream程中,您需要一个历史logging来logging需要花费的时间。
您还可以使用--high
和/或--medium
选项来指定一个长度阈值,以秒为单位,gnomon将以红色或黄色突出显示时间戳。 而且你也可以做其他一些事情。
如果你想要更高的精度,使用%N
和date
(并且使用bc
作为diff,因为$(())
只能处理整数)。
以下是如何做到这一点:
start=$(date +%s.%N) # do some stuff here dur=$(echo "$(date +%s.%N) - $start" | bc) printf "Execution time: %.6f seconds" $dur
例:
start=$(date +%s.%N); \ sleep 0.1s; \ dur=$(echo "$(date +%s.%N) - $start" | bc); \ printf "Execution time: %.6f seconds\n" $dur
结果:
Execution time: 0.104623 seconds
如果您打算稍后使用时间进行计算,请学习如何使用/usr/bin/time
的-f
选项来输出节省时间的代码 。 下面是我最近使用的一些代码来获取和sorting整个学生程序的执行时间:
fmt="run { date = '$(date)', user = '$who', test = '$test', host = '$(hostname)', times = { user = %U, system = %S, elapsed = %e } }" /usr/bin/time -f "$fmt" -o $timefile command args...
我后来连接了所有的$timefile
文件,并将输出$timefile
给一个Lua解释器 。 你可以用Python或bash或者你喜欢的语法来做同样的事情。 我喜欢这种技术。
你可以使用time
和subshell ()
:
time ( for (( i=1; i<10000; i++ )); do echo 1 >/dev/null done )
或在同一个shell {}
:
time { for (( i=1; i<10000; i++ )); do echo 1 >/dev/null done }
如果您只需要第二个精度,则可以使用内置的$SECONDS
variables来计算shell已经运行的秒数。
while true; do start=$SECONDS some_long_running_command duration=$(( SECONDS - start )) echo "This run took $duration seconds" if some_condition; then break; fi done
方式是
$ > g++ -lpthread perform.c -o per $ > time ./per
输出是>>
real 0m0.014s user 0m0.010s sys 0m0.002s