この質問があまりにも一般的ではないことを願っています。私はシェルスクリプトに初めてアクセスし、コンピュータアーキテクチャ/非スクリプトプログラミングの背景を持っています。私が作業しているスクリプトは、スクリプト全体の周りにサブシェルを作成することによって作成されることはほとんどありません。自分が作成しているスクリプトからサブシェルにラップできる場合、それを行うと、私を呼び出す他のスクリプトと混同されるのを防ぐことができます。このアプローチに関連するいくつかのオーバーヘッドのため、これは一般的な慣行ではありませんか?私はこれをオンラインで見つけるのに苦労しています。
例:
#!/bin/bash
( #Start of subshell
echo "Some stuff here"
) #End of subshell
答え1
サブシェルにはオーバーヘッドがあります。
システム内の最小フォーク実行コスト(ファイルがコールドされていない状態でディスク上でプログラムを実行するとき)はおよそ、2ms
最小フォークコストはおおよそです1ms
。
exec
サブシェルの場合、ファイルを編集する必要はないので、コストフォークについてのみ話しています。サブシェルが合理的に低く保たれると、1ms
人間指向のプログラムでは無視できます。私は人間がこれより早く起こっていることに気付くことができるとは思わない(現代のスクリプト言語ソルバーが最新の状況を50ms
始めるのにかかる時間です(python
ここではルビーについて話しています)。)rvm
nodejs
100ms
ただし、ループを追加してから、バッチ全体をstdoutとして関数を印刷して、かなり一般的なバックティックまたは$()
パターンを置き換えることができます。 )。return
printf -v
これバッシュ完了パッケージは、渡された変数名で返すために以下に説明する手法を使用して、このサブシェルのコストを特に防ぎます。http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
比較する
time for((i=0;i<10000;i++)); do echo "$(echo hello)"; done >/dev/null
そして
time for((i=0;i<10000;i++)); do echo hello; done >/dev/null
fork
システムのオーバーヘッドがいくらであるかについての良い見積もりを提供する必要があります。
答え2
私のシステムでPSkocikが提供した優れたコードを実行しても無視できる結果が出ました。
しかし、この例は本当に重要です。基本コマンドとサブシェルコマンドです。
MyPath="path/name.ext"
# this takes forever
time for((i=0;i<10000;i++)); do echo "$(basename ${MyPath} )"; done >/dev/null
#this is over 100x less time
time for((i=0;i<10000;i++)); do echo "${MyPath##*/}"; done >/dev/null