Я всегда думал, что единственным преимуществом использования тире вместо bash является то, что тире меньше, и поэтому во многих случаях тире запускается быстрее во время загрузки.
Но я провел некоторое исследование и обнаружил, что некоторые люди переносят все свои сценарии в надежде, что они будут работать быстрее, и я также нашел это в статье DashAsBinSh в Ubuntu Wiki:
Основной причиной переключения оболочки по умолчанию была эффективность . bash - превосходная полнофункциональная оболочка, подходящая для интерактивного использования; действительно, это все еще оболочка входа по умолчанию. Тем не менее, он довольно большой и медленно запускается и работает по сравнению с тире.
В настоящее время я использую множество сценариев bash для многих вещей в моей системе, и моя проблема в том, что у меня есть определенный сценарий, который я запускаю непрерывно 24/7, который порождает около 200 детей, которые вместе нагревают мой компьютер на 10 ° C больше, чем при обычном использовании.
Это довольно большой скрипт с множеством ошибок, поэтому его перенос на POSIX или какую-либо другую оболочку будет очень трудоемким (и POSIX не имеет особого значения для личного использования), но было бы целесообразно, если бы я мог уменьшить часть этого Использование процессора. Я знаю, что есть и другие вещи, которые нужно учитывать, например, вызывать внешний двоичный файл как sed
для простого bashism, например ${foo/bar}
, или grep
вместо =~
.
TL; DR - действительно ли bash медленнее запускается и работает по сравнению с dash? Существуют ли другие оболочки Unix, более эффективные, чем bash?
источник
[
также должен быть встроенным.bash
Раньше был очень медленным. В последнее время он добился большого прогресса, но в большинстве случаев он все еще медленнее, чем большинство других оболочек.[ "$foo" != "${foo#*bar}" ]
обрабатывает вашу вещь grep. Иsed
главное:while [ "$foo" != "${foo#*bar}" ]; do s=$s${foo%%bar*} foo=${foo#*bar} ; done ; foo=$s$foo
. Вы можете поместить любую вещь в функцию.Ответы:
SHELL SEQ:
Вероятно, полезный способ оценки производительности оболочки - многократно выполнять очень простые простые оценки. Я думаю, что важно не просто зацикливать, а зацикливать ввод , потому что оболочка должна читать
<&0
.Я думал, что это дополнит тесты, которые @cuonglm уже опубликовал, потому что он демонстрирует производительность отдельного процесса оболочки после его запуска, в отличие от его, который демонстрирует, насколько быстро загружается процесс оболочки при вызове. Таким образом, между нами мы покрываем обе стороны медали.
Вот функция для облегчения демонстрации:
Он либо увеличивает переменную один раз за чтение новой строки, либо, в случае небольшой оптимизации, если это возможно, увеличивает ее до 50 раз за чтение новой строки. Каждый раз, когда переменная увеличивается, она печатается в
stdout
. Он ведет себя во многом как своего родаseq
крестnl
.И просто, чтобы было очень ясно, что он делает - вот несколько усеченных
set -x;
выводов после их вставки непосредственно передtime
функцией выше:Итак, каждая оболочка сначала называется так:
... чтобы сгенерировать ввод, который ему нужно будет зациклить, когда он читает
3<<\SCRIPT
- или когда этоcat
произойдет, в любом случае. И с другой стороны,|pipe
он снова называет себя так:Так что кроме начального вызова
env
(потому чтоcat
фактически вызывается в предыдущей строке) ; никакие другие процессы не вызываются с момента его вызова до его выхода. По крайней мере, я надеюсь, что это правда.Перед цифрами ...
Я должен сделать некоторые заметки о переносимости.
posh
не любит$((n=n+1))
и настаивает на$((n=$n+1))
mksh
не имеетprintf
встроенного в большинстве случаев. В более ранних тестах он сильно отставал - он вызывал/usr/bin/printf
каждый прогон. Отсюда иecho -n
выше.может быть больше, как я помню это ...
Во всяком случае, на номера:
Это заставит их всех за один раз ...
АРБИТРАЖ = МОЖЕТ ОК?
Тем не менее, это довольно произвольный тест, но он проверяет входные данные чтения, арифметическую оценку и расширение переменной. Возможно не всесторонний, но возможно близко к там.
РЕДАКТИРОВАТЬ Teresa e Junior : @mikeserv и я провели много других тестов (подробности см. В нашем чате ), и мы обнаружили, что результаты можно суммировать следующим образом:
grep
,sed
,sort
и т.д., которые не имеют так много особенностей , как обычно используются GNU коммунальные услуги, но можно сделать работу столько же.источник
4.2.37(1)-release
из Debian и4.2.45(2)-release
из Porteus LiveCD (Slackware). Безnull=
, вместо вывода чисел, это работает так, как будто я постоянно нажимаю Return , тогда мне приходится убивать bash с помощью SIGKILL .bash --posix
, но безрезультатно.zsh
.zsh
будет угонятьtty
и хорошо, он запустит интерактивную оболочку. Я ожидаю,bash
что сделаю то же самое - вот почему я осторожен, чтобы назвать только его--posix
ссылку. Я могу сделать так, как вы ожидаете, для большинства из них, но это может быть больше работы, чем стоит. Ты звонишьbash
или звонишьsh
?Давай сделаем эталон.
С
bash
:С
dash
:Каждая итерация только запускает оболочку и ничего не делает с оператором no-op - двоеточие , а затем завершается.
Как показывает результат, он
dash
работает намного быстрее, чемbash
при запуске.dash
меньше и зависит от менее общей библиотеки, чемbash
:Это о времени запуска, как о работе. Давайте сделаем еще один тест:
С помощью простого теста
1 = 1
,dash
все еще намного быстрее, чемbash
.источник
seq 1 100000
должно бытьseq 1 1000
?dash
теста это толькоseq 1 1000
?1000
для запуска и1000000
для работы, исправлено.Вот некоторые моменты запуска различных оболочек в сертифицированной UNIX (Mac OS X 10.10.3). Я переписал тест, чтобы использовать tcsh для управления циклами, чтобы тестируемая оболочка не была той, которая контролировала циклы. Для каждой оболочки цикл выполняется пять раз перед синхронизацией, чтобы гарантировать, что исполняемый файл оболочки и сценарии находятся в кэше.
Как видите, нет однозначного победителя, но есть один окончательный проигравший. В любом случае, bash 4 заметно медленнее, чем bash 3. Dash работает хорошо, но, учитывая, что ksh93 теперь открыт с открытым исходным кодом, нет реальной причины не использовать его для всего (извиняюсь, если я неправильно понимаю какие-либо тонкости лицензирования): ksh93 быстрый, надежный и де-факто стандарт в земле UNIX (если не в GNU / Linux-земле); он предоставляет расширенный набор функций оболочки POSIX (насколько я понимаю, оболочка POSIX была основана на ksh88); он равен bash как интерактивная оболочка, хотя и запаздывает по сравнению с tcsh. И проигравший, конечно, зш.
источник
Здесь слишком много несправедливых тестовых примеров во многих ответах. Если вы тестируете две оболочки, используйте правильный синтаксис для каждой из них. А в bash двойные скобки намного быстрее и надежнее, чем одинарные, поэтому разница в скорости намного меньше. Также используйте оптимизированные bashisms, и тогда эти различия в скорости также более менее. В моей системе Bash работает как ад, с интенсивным использованием bashisms. И эквиваленты posix в тире здесь медленнее. Это не правильно, что тире всегда в несколько раз быстрее, чем bash. Действительно несправедливо сравнивать командные строки posix в обеих, которые всегда могут быть самыми быстрыми. На мой взгляд, posix сильно устарел. И с точки зрения совместимости, сегодня действительно сложно найти соответствующие системы, они не использовали оболочку bash.
Хорошее сравнение: использовать наилучшую возможную командную строку в каждой оболочке, чтобы завершить определенную работу. Не только точно такая же командная строка, когда только одна оболочка действительно имеет здесь преимущество. Подобные сравнения ненадежны и не показывают реальных результатов конкурентов. Я вижу на своей повседневной работе, какая оболочка быстрее во многих случаях использования.
Например, чтобы заменить все
a
символы в строке сb
символами, в Баше вы можете написать в"${varname//a/b}"
то время как в тире вы должны вызвать внешний инструмент , как это:"$(echo "$varname" | sed 's/a/b/g')"
. Если вам придется повторять это несколько сотен раз - использование bashism может дать вам 2-кратное ускорение.источник