6

興味がある場合は、Bashでの関数呼び出しが実際にどれほど高価であるかについての情報源はありますか?それらの中でコードを直接実行するよりも数倍遅いと思いますが、これについては何も見つからないようです。

4

1 に答える 1

12

私は、bash でプログラミングする際にパフォーマンスを気にする必要がないという意見には同意しません。それは実際には非常に良い質問です。

trueこれは、組み込みとコマンドを比較した可能なベンチマークです。trueその完全なパスは/bin/true私のマシンにあります。

私のマシンで:

$ time for i in {0..1000}; do true; done

real    0m0.004s
user    0m0.004s
sys 0m0.000s
$ time for i in {0..1000}; do /bin/true; done

real    0m2.660s
user    0m2.880s
sys 0m2.344s

すばらしい!これは、(私のマシンで) プロセスを fork するだけで約 2 から 3 ミリ秒無駄になります!

そのため、次に処理する大きなテキスト ファイルがある場合は、パイプさcatれた s、greps、awks、cuts、trs、seds 、 heads 、 tails 、s の (遅れた) 長いチェーンを回避しますyou-name-it。その上、UNIX パイプと非常に遅い (それはあなたの次の質問ですか?)。

1000 行のファイルがあり、各行に 1 cat、a grep、a、 a の順に入力するsedawk(いいえ、笑わないでください。このサイトの投稿を調べてみると、さらに悪いことがわかります!)、すでに (私のマシンでは) 少なくとも 2*4*1000=8000ms=8s を浪費しているだけで、愚かで役に立たないプロセスをフォークしています。

アップデート。パイプに関するコメントに答えるには...

サブシェル

サブシェルは非常に遅いです:

$ time for i in {1..1000}; do (true); done

real    0m2.465s
user    0m2.812s
sys 0m2.140s

すばらしい!サブシェルあたり2ms以上(私のマシン上)。

パイプ

パイプも非常に遅いです (これはパイプがサブシェルを含むという事実に関して明らかなはずです):

$ time for i in {1..1000}; do true | true; done

real    0m4.769s
user    0m5.652s
sys 0m4.240s

すばらしい!(私のマシンでは) パイプごとに 4 ミリ秒を超えるため、パイプだけで 2 ミリ秒です (サブシェルの時間を差し引いて)。

リダイレクション

$ time for i in {1..1000}; do true > file; done

real    0m0.014s
user    0m0.008s
sys 0m0.008s

それでかなり速いです。

わかりました、おそらくファイルの作成でそれが動作していることも見たいでしょう:

$ rm file*; time for i in {1..1000}; do true > file$i; done

real    0m0.030s
user    0m0.008s
sys 0m0.016s

それでもそこそこ速い。

パイプとリダイレクト:

あなたのコメントでは、次のように述べています。

sed '' filein > filetmp; sed '' filetmp > fileout

sed '' filein | sed '' > fileout

(もちろん、sed(通常は可能です) の 1 つのインスタンスを使用するのが最善ですが、それでは質問の答えにはなりません。)

それを確認しましょう:

面白い方法:

$ rm file*
$ > file
$ time for i in {1..1000}; do sed '' file | sed '' > file$i; done

real    0m5.842s
user    0m4.752s
sys 0m5.388s
$ rm file*
$ > file
$ time for i in {1..1000}; do sed '' file > filetmp$i; sed '' filetmp$i > file$i; done

real    0m6.723s
user    0m4.812s
sys 0m5.800s

したがって、一時ファイル (sed 用) を使用するよりも、パイプを使用する方が高速に思えます。実際、これは行を入力しなくても理解できたはずです。パイプでは、最初のパイプがsed何かを吐き出すとすぐに、2 番目のパイプsedがデータの処理を開始します。2 番目のケースでは、1 番目sedがそのジョブを実行し、次に 2 番目sedがそのジョブを実行します。

したがって、私たちの実験は、パイプがリダイレクトよりも優れているかどうかを判断する良い方法ではありません.

プロセス代替はどうですか?

$ rm file*
$ > file
$ time for i in {1..1000}; do sed '' > file$i < <(sed '' file); done

real    0m7.899s
user    0m1.572s
sys 0m3.712s

うわー、それは遅いです !ねえ、でもユーザーとシステムのCPU使用率を観察してください。他の2つの可能性よりもはるかに少ないです(誰かがそれを説明できれば...)

于 2012-12-10T14:32:34.677 に答える