SHELL SEQ:
Вероятно, полезный способ оценки производительности оболочки - многократно выполнять очень простые простые оценки. Я думаю, что важно не просто зацикливать, а зацикливать ввод , потому что оболочка должна читать <&0
.
Я думал, что это дополнит тесты, которые @cuonglm уже опубликовал, потому что он демонстрирует производительность отдельного процесса оболочки после его запуска, в отличие от его, который демонстрирует, насколько быстро загружается процесс оболочки при вызове. Таким образом, между нами мы покрываем обе стороны медали.
Вот функция для облегчения демонстрации:
sh_bench() ( #dont 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
Он либо увеличивает переменную один раз за чтение новой строки, либо, в случае небольшой оптимизации, если это возможно, увеличивает ее до 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 и я провели много других тестов (подробности см. В нашем чате ), и мы обнаружили, что результаты можно суммировать следующим образом:
- Если вам нужна скорость, определенно используйте dash , она намного быстрее любой другой оболочки и примерно в 4 раза быстрее, чем bash .
- В то время как BusyBox оболочка «s может быть гораздо медленнее , чем тир , в некоторых тестах он может быть быстрее, потому что он обладает многими из своих собственных пользовательских утилит, как
grep
, sed
, sort
и т.д., которые не имеют так много особенностей , как обычно используются GNU коммунальные услуги, но можно сделать работу столько же.
- Если скорость - это не все, что вас волнует, ksh (или ksh93 ) можно считать лучшим компромиссом между скоростью и функциями. Его скорость сравнивается с меньшим mksh , который намного быстрее, чем bash , и у него также есть некоторые уникальные особенности, такие как арифметика с плавающей запятой .
- Хотя bash славится своей простотой, стабильностью и функциональностью, он был самым медленным из всех оболочек в большинстве наших тестов и с большим отрывом.