シェルループは遅く、bashのループは最も遅いです。シェルは、ループで重い作業を行うためのものではありません。シェルは、データのバッチでいくつかの最適化された外部プロセスを起動することを目的としています。
とにかく、シェルループの比較方法に興味があったので、少しベンチマークを作成しました。
#!/bin/bash
export IT=$((10**6))
echo POSIX:
for sh in dash bash ksh zsh; do
TIMEFORMAT="%RR %UU %SS $sh"
time $sh -c 'i=0; while [ "$IT" -gt "$i" ]; do i=$((i+1)); done'
done
echo C-LIKE:
for sh in bash ksh zsh; do
TIMEFORMAT="%RR %UU %SS $sh"
time $sh -c 'for ((i=0;i<IT;i++)); do :; done'
done
G=$((10**9))
TIMEFORMAT="%RR %UU %SS 1000*C"
echo 'int main(){ int i,sum; for(i=0;i<IT;i++) sum+=i; printf("%d\n", sum); return 0; }' |
gcc -include stdio.h -O3 -x c -DIT=$G -
time ./a.out
(
詳細:
- CPU:Intel(R)Core(TM)i5 CPU M 430 @ 2.27GHz
- ksh:バージョンsh(AT&T Research)93u + 2012-08-01
- bash:GNU bash、バージョン4.3.11(1)-release(x86_64-pc-linux-gnu)
- zsh:zsh 5.2(x86_64-unknown-linux-gnu)
- ダッシュ:0.5.7-4ubuntu1
)
(省略された)結果(反復あたりの時間)は次のとおりです。
POSIX:
5.8 µs dash
8.5 µs ksh
14.6 µs zsh
22.6 µs bash
C-LIKE:
2.7 µs ksh
5.8 µs zsh
11.7 µs bash
C:
0.4 ns C
結果から:
少し高速なシェルループが必要な場合、[[
構文があり、高速なシェルループが必要な場合は、高度なシェルを使用し、Cのようなforループも使用できます。次に、Cのようにforループを使用します。while [
同じシェルの-loopsの約2倍の速さです。
- kshには、反復あたり
for (
約2.7µsの最速ループがあります
- ダッシュボードには反復あたり
while [
約5.8µsの最速ループがあります
C forループは、小数点以下3桁から4桁高速です。(トーバルズはCが大好きだと聞きました)。
最適化されたC forループは、bashのwhile [
ループ(最も遅いシェルループ)より56500 倍速く、kshのfor (
ループ(最も速いシェルループ)よりも6750倍高速です。
繰り返しますが、シェルの典型的なパターンは、外部の最適化されたプログラムのいくつかのプロセスにオフロードすることですので、シェルの速度はそれほど重要ではありません。
このパターンを使用すると、シェルを使用すると、Pythonスクリプトよりも優れたパフォーマンスでスクリプトを記述しやすくなります(前回チェックしたとき、Pythonでプロセスパイプラインを作成するのはかなり面倒でした)。
考慮すべきもう1つのことは、起動時間です。
time python3 -c ' '
PCでは30〜40ミリ秒かかりますが、シェルは約3ミリ秒かかります。多くのスクリプトを起動すると、これはすぐに追加され、Pythonが開始するのにかかる余分な27〜37ミリ秒で非常に多くのことができます。小さなスクリプトは、その時間枠内で何度か終了できます。
(NodeJsはおそらく、開始するのに約100ミリ秒かかるため、この部門ではおそらく最悪のスクリプトランタイムです(開始した後でも、スクリプト言語の中から優れたパフォーマンスを見つけるのは難しいでしょう)。