我想在一些不同的条件下在linux shell中执行一些东西,并且能够输出每次执行的执行时间。

我知道我可以写一个perl或python脚本,可以做到这一点,但有一种方法我可以在shell中做到这一点吗?(恰好是bash)


当前回答

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++代码?

其他回答

方法是

$ > g++ -lpthread perform.c -o per
$ > time ./per

输出为>>

real    0m0.014s
user    0m0.010s
sys     0m0.002s

要逐行测量delta,请尝试用指针测量。

$ npm install -g gnomon
$ <your command> | gnomon --medium=1.0 --high=4.0 --ignore-blank --real-time=100

一个命令行实用程序,有点像moreutils的ts,用于将时间戳信息预先添加到另一个命令的标准输出中。对于长时间运行的流程非常有用,因为您需要记录花费如此长时间的事情。

还可以使用——high和/或——medium选项指定以秒为单位的长度阈值,超过该阈值,gnomon将以红色或黄色突出显示时间戳。你还可以做一些其他的事情。

您可以获得比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
#!/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"

使用内置的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