иногда примеры полезны.
f='fred';y=0;time for ((i=0;i<1000;i++));do if [[ -n "$( grep 're' <<< $f )" ]];then ((y++));fi;done;echo $y
real 0m3.878s
user 0m0.794s
sys 0m2.346s
1000
f='fred';y=0;time for ((i=0;i<1000;i++));do if [[ -z "${f/*re*/}" ]];then ((y++));fi;done;echo $y
real 0m0.041s
user 0m0.027s
sys 0m0.001s
1000
f='fred';y=0;time for ((i=0;i<1000;i++));do if grep -q 're' <<< $f ;then ((y++));fi;done >/dev/null;echo $y
real 0m2.709s
user 0m0.661s
sys 0m1.731s
1000
Как видите, в этом случае разница между использованием grep в подоболочке и расширением параметров для выполнения одного и того же базового теста почти в 100 раз превышает общее время.
Следуя дальше вопросу и принимая во внимание приведенные ниже комментарии, которые явно не указывают на то, что они пытаются указать, я проверил следующий код: https://unix.stackexchange.com/questions/284268/какие-накладныерасходы-использования-подоболочек
time for((i=0;i<10000;i++)); do echo "$(echo hello)"; done >/dev/null
real 0m12.375s
user 0m1.048s
sys 0m2.822s
time for((i=0;i<10000;i++)); do echo hello; done >/dev/null
real 0m0.174s
user 0m0.165s
sys 0m0.004s
Это на самом деле намного хуже, чем я ожидал. Фактически почти на два порядка медленнее по общему времени и почти на ТРИ порядка медленнее по времени системных вызовов, что абсолютно невероятно. https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html
Обратите внимание, что цель демонстрации этого состоит в том, чтобы показать, что если вы используете метод тестирования, который довольно легко привыкнуть к использованию, grep подоболочки, или sed, или gawk (или встроенный bash, например, echo), который для меня плохая привычка, к которой я склонен быстро взламывать, стоит понимать, что это приведет к значительному снижению производительности, и, вероятно, стоит избегать их, если встроенные функции bash могут справиться с работой изначально.
Тщательно изучив использование подоболочек в больших программах и по возможности заменив их другими методами, я смог сократить примерно 10% общего времени выполнения только что выполненного набора оптимизаций (не первого и не последнего, раз я это сделал, его уже несколько раз оптимизировали, так что выигрыш еще 10% на самом деле весьма значителен)
Так что стоит быть в курсе.
Поскольку мне было любопытно, я хотел подтвердить, что «время» говорит нам здесь: https://en.wikipedia.org/wiki/Time_(Unix)
Общее время ЦП представляет собой комбинацию количества времени, которое ЦП или ЦП тратят на выполнение некоторых действий для программы, и количества времени, которое они тратят на выполнение системных вызовов для ядра от имени программы. Когда программа перебирает массив, она накапливает процессорное время пользователя. И наоборот, когда программа выполняет системный вызов, такой как exec или fork, она накапливает системное процессорное время.
Как вы можете видеть, в частности, в тесте эхо-цикла, стоимость форков очень высока с точки зрения системных вызовов ядра, эти форки действительно складываются (в 700 раз!!! больше времени тратится на системные вызовы).
Я нахожусь в постоянном процессе решения некоторых из этих вопросов, поэтому эти вопросы на самом деле весьма актуальны для меня и глобального сообщества пользователей, которым нравится рассматриваемая программа, то есть для меня это не какой-то загадочный академический момент, это реальный мир, с реальными последствиями.
person
Lizardx
schedule
29.07.2017