我想在一些不同的条件下在linux shell中执行一些东西,并且能够输出每次执行的执行时间。
我知道我可以写一个perl或python脚本,可以做到这一点,但有一种方法我可以在shell中做到这一点吗?(恰好是bash)
我想在一些不同的条件下在linux shell中执行一些东西,并且能够输出每次执行的执行时间。
我知道我可以写一个perl或python脚本,可以做到这一点,但有一种方法我可以在shell中做到这一点吗?(恰好是bash)
当前回答
如果您打算以后使用时间来计算,请学习如何使用/usr/bin/time的-f选项来输出节省时间的代码。下面是我最近使用的一些代码,用于获取和排序整个班级的学生程序的执行时间:
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文件连接起来,并将输出输出到Lua解释器中。你可以用Python或bash或任何你喜欢的语法做同样的事情。我喜欢这个技巧。
其他回答
使用内置的time关键字:
$ help time time: time [-p] PIPELINE Execute PIPELINE and print a summary of the real time, user CPU time, and system CPU time spent executing PIPELINE when it terminates. The return status is the return status of PIPELINE. The `-p' option prints the timing summary in a slightly different format. This uses the value of the TIMEFORMAT variable as the output format.
例子:
$ time sleep 2
real 0m2.009s user 0m0.000s sys 0m0.004s
您可以获得比bash内置时间(即time(1), Robert Gamble提到过)更详细的信息。通常这是/usr/bin/时间
编者按: 为了确保您调用的是外部实用程序time而不是shell的time关键字,请以/usr/bin/time来调用它 time是posix强制的实用程序,但它需要支持的唯一选项是-p。 特定的平台实现特定的、非标准的扩展:-v与GNU的time实用程序一起工作,如下所示(问题被标记为linux);BSD/macOS实现使用-l来产生类似的输出-参见man 1次。
详细输出示例:
$ /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
perf stat Linux命令行实用程序
这个工具对于获取时间来说是多余的。但是它可以为您做更多的事情,帮助您分析和修复速度慢,这是值得了解的。Ubuntu 22.04安装:
sudo apt install linux-tools-common linux-tools-generic
echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
用法:
perf stat <mycmd>
使用stress-ng运行示例:
perf stat stress-ng --cpu 1 --cpu-method matrixprod -t 5
样例输出:
Performance counter stats for 'stress-ng --cpu 1 --cpu-method matrixprod -t 5':
5,005.46 msec task-clock # 0.999 CPUs utilized
88 context-switches # 17.581 /sec
1 cpu-migrations # 0.200 /sec
1,188 page-faults # 237.341 /sec
18,847,667,167 cycles # 3.765 GHz
26,544,261,897 instructions # 1.41 insn per cycle
3,239,655,001 branches # 647.225 M/sec
25,393,369 branch-misses # 0.78% of all branches
5.012218939 seconds time elapsed
4.998051000 seconds user
0.009122000 seconds sys
perf还可以做一些更高级的事情,例如,在这里我将展示如何使用它来分析代码:我如何分析运行在Linux上的c++代码?
如果您想要更精确,请使用%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
要逐行测量delta,请尝试用指针测量。
$ npm install -g gnomon
$ <your command> | gnomon --medium=1.0 --high=4.0 --ignore-blank --real-time=100
一个命令行实用程序,有点像moreutils的ts,用于将时间戳信息预先添加到另一个命令的标准输出中。对于长时间运行的流程非常有用,因为您需要记录花费如此长时间的事情。
还可以使用——high和/或——medium选项指定以秒为单位的长度阈值,超过该阈值,gnomon将以红色或黄色突出显示时间戳。你还可以做一些其他的事情。