スクリプトを実行する最速の方法は何ですか?


22

私はスクリプトを実行する最速の方法は何だろうと思っていました、私は端末でスクリプトの出力を表示するか、ファイルにリダイレクトするか、または場合によっては速度が異なることを読んでいます/dev/null

したがって、出力が重要でない場合、スクリプトが最小であっても、スクリプトをより速く動作させるための最速の方法は何ですか?

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


「通常のファイルへのリダイレクト」と「/ dev / nullへのリダイレクト」を比較すると、私には奇妙に思えます
...-el.pescado

回答:


31

最近の端末は、主にグラフィックスカードが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
  • xterm、260x78:

    $ 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

6
@Kingofkechは200行/秒未満です。大した違いはありません。(比較のためtimeout 1 yes "This is a looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line"に、MBPに1秒で100000行以上を印刷します。)
muru

4
@Kingofkechこれがスクリプトの場合、ファイルを編集し、不要な出力を出力する行をコメント化します。特に、これが300万回実行される外部コマンド(シェル組み込みではない)である場合、多くを獲得できます
...-jimmij

2
「かつて」の狭い解釈。vt220ターミナルは、今日のターミナルエミュレータよりもかなり遅いです。また、SUN Sparcワークステーション(私が使用したワークステーション)のコンソールは非常に低速だったため、大きなプロジェクトをコンパイルするときに出力をファイルにリダイレクトするだけで、コンパイル時間が大幅に短縮されました。
クサラナナンダ

1
@Kusalanandaそれは本当です。20年前のHP-UX xtermと比較しxtermsて、30年前のHP Apolloのクロールに使用されていました。ただし、15年前のMatroxビデオカードを搭載したLinuxコンソールは、20年前のS3カードを搭載した同じLinuxコンソールよりも低速でした。また、最新のカードに高解像度のフレームバッファーを備えたLinuxコンソールは、まったく使用できません。:)
桂佐藤

6
@Kingofkechそれは約2400 bpsです。私たちの何人かは、実際にそれらの速度で何年も生きました。:)
桂佐藤

14

私は桂佐藤の答えに本能的に同意したでしょう。それは理にかなっている。ただし、テストするのは簡単です。

100万行の画面への書き込み、ファイルへの書き込み(追加)、およびへのリダイレクトをテストしました/dev/null。これらを順番にテストしてから、5回繰り返しました。これらは私が使用したコマンドです。

$ 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)

ジョン・クーゲルマンがコメントで指摘しているように、これは多くのオーバーヘッドを追加します。質問が立つように、これは実際にそれをテストするための正しい方法ではありませんが、それははっきりから繰り返し再開いたファイルのコストを示しているように私はそれをここに残しておきます内のスクリプト自体。

時間対出力のプロット

この場合、結果は逆になります。


FWIW回答に簡単なベンチマークを追加しました。特に、Linuxコンソールはの200倍以上遅くxterm、これはの3倍遅くなり/dev/nullます。
桂佐藤

また、レート制限を使用してテストする必要があります。OPの出力は約200行/秒です。
ムル

@muru行を印刷して、1/200秒待ってから繰り返しますか?試すことはできますが、同様の結果になると思いますが、信号がノイズを克服するのにもっと時間がかかるだけです。分析前に待ち時間を差し引くこともできますが。
-Sparhawk

@Sparhawkそのようなもの。そのレベルの出力では、CPUは出力レートを落とすことなくディスプレイを更新するのに十分な時間があると思います。プログラムが一時停止せずに行を吐き出すだけである場合、表示が更新されてボトルネックが発生するよりも速く端末バッファがいっぱいになります。
ムル

3

スクリプトを高速化する別の方法は、より高速なシェルインタープリターを使用することです。POSIX bash ビジーループの速度を比較し、v4.4ksh 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

サブセット内のコマンドbashとがkshある後方互換のコマンドの全てにdashbashそのサブセットのコマンドのみを使用するスクリプトはで動作するはずdashです。

bash新しい機能を使用する一部のスクリプトは、別のインタープリターに変換できます。場合bash-スクリプトは、新しい機能に大きく依存している、それは価値が気ではないかもしれないいくつかのbash機能が両方のコードに簡単で改善している、より効率的で、(にもかかわらずbash、一般的に遅くなる)、そのことをdash実行している伴う可能性がある(等価他のいくつかのコマンド)、遅くなります。

疑わしい場合は、テストを実行してください...


bashスクリプトを高速化するには、bashまたはkshで書き換える必要がありますか?
-Kingofkech

@Kingofkech bash用に作成したコードは、kshまたはダッシュのコードに簡単に修正できる可能性があります。インタプリタを変更してみてください。
-bli
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.