興味がある場合は、Bashでの関数呼び出しが実際にどれほど高価であるかについての情報源はありますか?それらの中でコードを直接実行するよりも数倍遅いと思いますが、これについては何も見つからないようです。
1 に答える
私は、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、grep
s、awk
s、cut
s、tr
s、sed
s 、 head
s 、 tail
s 、s の (遅れた) 長いチェーンを回避しますyou-name-it
。その上、UNIX パイプと非常に遅い (それはあなたの次の質問ですか?)。
1000 行のファイルがあり、各行に 1 cat
、a grep
、a、 a の順に入力するsed
とawk
(いいえ、笑わないでください。このサイトの投稿を調べてみると、さらに悪いことがわかります!)、すでに (私のマシンでは) 少なくとも 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つの可能性よりもはるかに少ないです(誰かがそれを説明できれば...)