私はいつもbashの代わりにダッシュを使用する唯一の利点は、ダッシュが小さいので、多くのダッシュインスタンスが起動時により早く開始されることだと思いました。
しかし、調査をしてみると、一部の人々はより速く実行されることを望んですべてのスクリプトをダッシュに移行するという事実を発見しました。記事でもこの内容を発見しました。ダッシュUbuntu Wikipediaから:
基本シェルを切り替える主な理由は効率。 bashはインタラクティブな使用に適した優れた機能を備えたシェルであり、実際にはまだデフォルトのログインシェルです。しかし、規模はかなり大きくてスロースタートそして運営するダッシュと比較。
最近私は私のシステムの多くの仕事にbashスクリプトをたくさん使っています。私の問題は、年中無休の24時間連続で実行する特定のスクリプトがあり、このスクリプトが一緒にマイコンピュータをダウンさせる約200の添え字を生成することです。最大10℃以上加熱されます。通常の使用時より
bashismがたくさん含まれているかなり大きなスクリプトなので、これをPOSIXや他のシェルに移植するのにかなりの時間がかかります(POSIXは個人的な用途にとってそれほど重要ではありません)。しかし、一部を減らすことができれば価値があるでしょう。 CPU使用量です。たとえば、sed
単純なbashismを呼び出すために外部バイナリを呼び出すなど、考慮する必要がある他のものがあることを知っています。${foo/bar}
grep
=~
長い話を短くbashの起動速度は本当に遅いです。そして運営するダッシュと比べると?より強力なUnixシェルはありますか?効率的なバッシュより?
ベストアンサー1
シェル順序:
おそらくシェルのパフォーマンスをベンチマークする便利な方法は、非常に小さくて簡単な評価を多数繰り返すことです。私は単にループを繰り返さないことが重要だと思います。入力する、シェルが読む必要があるからです<&0
。
私はこれがテストを補完すると思った@cuonglm 投稿しましたこれは、呼び出し時にシェルプロセスがどれだけ早くロードされるかを示すのではなく、呼び出し後の単一のシェルプロセスのパフォーマンスを示すためです。このように、我々は私たちの間のコインの両面を覆います。
簡単に実演できる機能は次のとおりです。
sh_bench() ( #don't copy+paste comments
o=-c sh=$(command -v "$1") ; shift #get shell $PATH; toss $1
[ -z "${sh##*busybox}" ] && o='ash -c' #cause its weird
set -- "$sh" $o "'$(cat <&3)'" -- "$@" #$@ = invoke $shell
time env - "$sh" $o "while echo; do echo; done|$*" #time (env - sh|sh) AC/DC
) 3<<-\SCRIPT
#Everything from here down is run by the different shells
i="${2:-1}" l="${1:-100}" d="${3:-
}"; set -- "\$((n=\$n\${n:++\$i}))\$d" #prep loop; prep eval
set -- $1$1$1$1$1$1$1$1$1$1 #yup
while read m #iterate on input
do [ $(($i*50+${n:=-$i})) -gt "$(($l-$i))" ] || #eval ok?
eval echo -n \""$1$1$1$1$1"\" #yay!
[ $((n=$i+$n)) -gt "$(($l-$i))" ] && #end game?
echo "$n" && exit #and EXIT
echo -n "$n$d" #damn - maybe next time
done #done
#END
SCRIPT #end heredoc
各改行を読むたびに変数を1回増やすか(可能であれば)、少しの最適化で各改行を読むたびに変数を50倍増やします。変数が増加するたびにに印刷されますstdout
。これは一種のseq
十字架のように動作しますnl
。
これが行うことを非常に明確にするために、上記の関数のset -x;
前に挿入した後にいくつかの切り捨てられた出力があります。time
time env - /usr/bin/busybox ash -c '
while echo; do echo; done |
/usr/bin/busybox ash -c '"'$(
cat <&3
)'"' -- 20 5 busybox'
したがって、各シェルはまず次のように呼び出されます。
env - $shell -c "while echo; do echo; done |..."
3<<\SCRIPT
...読み取り中に繰り返す必要がある入力を生成しますcat
。一方、|pipe
次のように自分自身を呼び出します。
"...| $shell -c '$(cat <<\SCRIPT)' -- $args"
だから初期の電話通話に加えてenv
(cat
実際には前の行から呼び出されたためです);呼び出された時点から終了するまで、他のプロセスは呼び出されません。少なくともそれが本当であることを願っています。
数字の前に...
移植性についていくつかのメモを取る必要があります。
posh
嫌い$((n=n+1))
で頑固$((n=$n+1))
mksh
printf
ほとんどの場合、組み込み機能はありません。初期テストでは、遅延が多く発生し、/usr/bin/printf
実行されるたびに呼び出されました。したがって、上記のような状況が発生しますecho -n
。おそらく私の記憶ではもっと多いかもしれません...
とにかく数字を見ると次のようになります。
for sh in dash busybox posh ksh mksh zsh bash
do sh_bench $sh 20 5 $sh 2>/dev/null
sh_bench $sh 500000 | wc -l
echo ; done
これにより、すべての作業を完了できます。
0dash5dash10dash15dash20
real 0m0.909s
user 0m0.897s
sys 0m0.070s
500001
0busybox5busybox10busybox15busybox20
real 0m1.809s
user 0m1.787s
sys 0m0.107s
500001
0posh5posh10posh15posh20
real 0m2.010s
user 0m2.060s
sys 0m0.067s
500001
0ksh5ksh10ksh15ksh20
real 0m2.019s
user 0m1.970s
sys 0m0.047s
500001
0mksh5mksh10mksh15mksh20
real 0m2.287s
user 0m2.340s
sys 0m0.073s
500001
0zsh5zsh10zsh15zsh20
real 0m2.648s
user 0m2.223s
sys 0m0.423s
500001
0bash5bash10bash15bash20
real 0m3.966s
user 0m3.907s
sys 0m0.213s
500001
誰=多分?
それでも、これはかなりランダムなテストですが、入力読み出し、算術評価、および変数拡張をテストします。包括的ではありませんが、おそらくそれに近いです。
編集者: Teresa e Junior:@mikeservと私は他の多くのテストを行いました(参照私たちのチャット詳細)結果を次のように要約できることを確認しました。
- 速度が必要な場合は必ず選択してくださいスプリント、これは他のシェルよりはるかに高速です。強く打つ。
- しかし、忙しい箱殻はおそらく良いと思います。スプリント、一般的に使用されるGNUユーティリティほど多くの機能はありませんが、それほど多くの作業を行うことができる、、などの独自の
grep
ユーザー空間ユーティリティが多いため、一部のテストではより速い場合があります。 。sed
sort
- 速度があなたのすべてではない場合ケシ(またはクッシュ 93)は、速度と機能性の間の最良の妥協点と見なすことができます。小さいものに比べて速度が速いムケシ、これよりも優れています。強く打つで、次のようないくつかのユニークな機能もあります。浮動小数点演算。
- しかし、強く打つ単純さ、安定性、機能性としてよく知られていますが、ほとんどのテストでは、すべてのシェルの中で最も遅く、速度も非常に多様でした。