运行脚本最快的方法是什么?

运行脚本最快的方法是什么?

我想知道运行脚本的最快方法是什么,我一直在读到在终端上显示脚本的输出、将其重定向到文件或可能之间存在速度差异/dev/null

因此,如果输出并不重要,那么让脚本更快运行的最快方法是什么,即使它是最小的。

bash ./myscript.sh 
-or-
bash ./myscript.sh > myfile.log
-or-
bash ./myscript.sh > /dev/null

答案1

现在的终端比以前慢了,主要是因为显卡不再关心2D加速。因此,确实,打印到终端可能会减慢脚本速度,特别是在涉及滚动时。

因此./script.sh比 慢./script.sh >script.log,而 又比 慢/script.sh >/dev/null,因为后者涉及的工作较少。然而,这是否对任何实际目的产生足够的影响取决于脚本产生的输出量和速度。如果您的脚本写入 3 行并退出,或者每隔几个小时打印 3 页,您可能不需要为重定向而烦恼。

编辑:一些快速(并且完全损坏)的基准测试:

  • 在 Linux 控制台中,240x75:

    $ time (for i in {1..100000}; do echo $i 01234567890123456789012345678901234567890123456789; done)
    real    3m52.053s
    user    0m0.617s
    sys     3m51.442s
    
  • xterm260x78 中:

    $ time (for i in {1..100000}; do echo $i 01234567890123456789012345678901234567890123456789; done)
    real    0m1.367s
    user    0m0.507s
    sys     0m0.104s
    
  • 重定向到 Samsung SSD 850 PRO 512GB 磁盘上的文件:

     $ time (for i in {1..100000}; do echo $i 01234567890123456789012345678901234567890123456789; done >file)
     real    0m0.532s
     user    0m0.464s
     sys     0m0.068s
    
  • 重定向至/dev/null

     $ time (for i in {1..100000}; do echo $i 01234567890123456789012345678901234567890123456789; done >/dev/null)
     real    0m0.448s
     user    0m0.432s
     sys     0m0.016s
    

答案2

我本能地会同意佐藤桂的回答;这说得通。然而,测试起来很容易。

我测试了向屏幕写入一百万行、写入(追加)到文件,然后重定向到/dev/null.我依次测试了每一个,然后进行了五次重复。这些是我使用的命令。

$ time (for i in {1..1000000}; do echo foo; done)
$ time (for i in {1..1000000}; do echo foo; done > /tmp/file.log) 
$ time (for i in {1..1000000}; do echo foo; done > /dev/null)

然后我在下面绘制了总时间。

时间与输出的关系图

如你看到的,佐藤桂的推测是正确的。按照佐藤桂的回答,我也怀疑限制因素将是输出,因此输出的选择不太可能对脚本的整体速度产生实质性影响。


FWIW,我原来的答案有不同的代码,其中附加了文件和/dev/null重定向里面循环。

$ rm /tmp/file.log; touch /tmp/file.log; time (for i in {1..1000000}; do echo foo >> /tmp/file.log; done) 
$ time (for i in {1..1000000}; do echo foo > /dev/null; done)

作为约翰·库格曼在撰写本文时的评论中指出,这增加了很多开销。就问题而言,这实际上并不是测试它的正确方法,但我将其留在这里,因为它清楚地显示了从以下位置重复重新打开文件的成本之内脚本本身。

时间与输出的关系图

在这种情况下,结果相反。

答案3

加快脚本速度的另一种方法是使用更快的 shell 解释器。比较a的速度POSIX繁忙循环,运行在bash v4.4,ksh v93u+20120801, 和dash v0.5.8

  1. bash

    time echo 'n=0;while [ $n -lt 1000000 ] ; do \
                      echo $((n*n*n*n*n*n*n)) ; n=$((n+1)); 
                   done' | bash -s > /dev/null
    

    输出:

    real    0m25.146s
    user    0m24.814s
    sys 0m0.272s
    
  2. ksh

    time echo 'n=0;while [ $n -lt 1000000 ] ; do \
                      echo $((n*n*n*n*n*n*n)) ; n=$((n+1)); 
                   done' | ksh -s > /dev/null
    

    输出:

    real    0m11.767s
    user    0m11.615s
    sys 0m0.010s
    
  3. dash

    time echo 'n=0;while [ $n -lt 1000000 ] ; do \
                      echo $((n*n*n*n*n*n*n)) ; n=$((n+1)); 
                   done' | dash -s > /dev/null
    

    输出:

    real    0m4.886s
    user    0m4.690s
    sys 0m0.184s
    

A子集bash和中的命令ksh向后兼容到 中的所有命令dash。仅使用该子集中的命令的脚本bash应与dash.

一些bash使用新功能的脚本可以转换为另一个解释器。如果bash脚本严重依赖较新的功能,则可能不值得麻烦 -一些新的bash功能是改进,更容易编码更高效(尽管bash通常较慢),因此dash等效的(可能涉及运行其他几个命令)会更慢。

如有疑问,请进行测试...

相关内容