Моя оболочка bash запускается до 3-4 секунд, а если я запускаю ее, --norc
она запускается немедленно.
Я начал «профилирование» /etc/bash.bashrc
и ~/.bashrc
вручную вставив return
заявления и ищут улучшения в скорости, но это не количественный процесс , и это не является эффективным.
Как я могу профилировать свои сценарии bash и посмотреть, какие команды запускаются больше всего?
time bash -c 'exit'
иtime bash -i -c 'exit'
и может играть с--norc
и--noprofile
.Ответы:
Если у вас есть GNU
date
(или другая версия, которая может выводить наносекунды), сделайте это в начале/etc/bash.bashrc
(или где бы вы ни хотели начать трассировку в любом сценарии Bash):Добавить
в конце
~/.bashrc
(или в конце раздела любого сценария Bash, трассировку которого вы хотите остановить). Это\011
восьмеричный символ табуляции.Вы должны получить журнал трассировки,
/tmp/bashstart.PID.log
который показывает временную метку seconds.nanoseconds каждой выполненной команды. Разница от одного раза к другому - это количество времени, которое занял промежуточный шаг.По мере того, как вы сужаете круг вопросов, вы можете двигаться дальше
set -x
иset +x
раньше (или выборочно ограничивать несколько интересующих разделов).Хотя он не такой детализированный, как
date
наносекунды GNU , Bash 5 включает переменную, которая дает время в микросекундах. Его использование избавляет вас от создания внешнего исполняемого файла для каждой строки и работает на Mac или где-либо еще, где нет GNUdate
- конечно, если у вас есть Bash 5. Измените настройкуPS4
:Как указано в @pawamoy, вы можете использовать
BASH_XTRACEFD
для отправки вывода трассировки в отдельный файловый дескриптор, если у вас Bash 4.1 или новее. Из этого ответа :Это приведет к тому, что вывод трассировки перейдет в
command.txt
оставленный файлstdout
иstdout
будет выводиться нормально (или будет перенаправлен отдельно).источник
exec
должен вернуть fd2 в нормальное состояние, так что вы должны вернуть приглашение.\D{...}
inPS4
позволяет расширять полностью произвольные строки формата времени без дополнительных затрат производительности на запускdate
в качестве подпроцесса.date
понимает,%N
а Bash 4.2 - нет (потомуstrftime(3)
что не понимает ) в системе GNU - так произвольно с ограничениями. Ваше мнение о производительности и разрешении является правильным, и пользователь должен сделать выбор с умом, помня, что снижение производительности является временным только во время отладки (и только тогда, когдаset -x
оно действует).Профилирование удар (4 ответа)
Изменить:
script
метод добавления в марте 2016 г.Прочитав это, и поскольку профилирование является важным шагом, я провел несколько тестов и исследований по всему этому вопросу SO и уже опубликовал ответы.
Есть 4+ ответа:
Последнее использование
script
,scriptreplay
и файл синхронизации .Напоследок, небольшое сравнение выступлений.
Использование
set -x
и,date
но с ограниченными вилкамиВозьмите идею @DennisWilliamson, но со следующим синтаксисом будет только одна начальная вилка на 3 команды:
Это будет выполняться
date
только один раз. Есть небольшая демонстрация / тест, чтобы показать, как это работает:Пример сценария:
Запустив этот сценарий, вы создаете 2 файла:
/tmp/sample-XXXX.log
и/tmp/sample-XXXX.tim
(где XXXX - это идентификатор процесса запущенного сценария).Вы можете представить их, используя
paste
:Или вы даже можете вычислить время разницы:
или на двух столбцах:
Может оказывать:
Использование
trap debug
и/proc/timer_list
на последних ядрах GNU / Linux без вилок .В последних ядрах GNU / Linux вы можете найти
/proc
файл с именемtimer_list
:Где текущее время - это сумма
5461935212966259 + 1383718821564493249
, но в наносекундах.Таким образом, для вычисления прошедшего времени нет необходимости знать смещение.
Для такого рода заданий я написал elap.bash (V2) , который будет получен с использованием следующего синтаксиса:
или
(Полный синтаксис см. В комментариях)
Итак, вы можете просто добавить эту строку в начало своего скрипта:
Маленький образец:
Сделайте рендеринг на моем хосте:
Использование
trap2
вместоtrap
аргумента исходной команды:Отрендерит две колонки последней команды и итога :
С помощью
strace
Да,
strace
справился бы:Зато можно было сделать много всего!
Использование более ограниченной команды:
Сбросим более легкое бревно:
В зависимости от того, что вы ищете, вы можете ввести более строгие ограничения:
Читать их будет немного сложнее:
Оригинальный Баш скрипт не так легко следовать в этом ...
Использование
script
,scriptreplay
и файл синхронизацииКак часть BSD Utils ,
script
(иscriptreplay
) - очень старый инструмент, который можно использовать для профилирования bash, с очень маленьким размером.Изготовим:
и сгенерируйте два файла:
Файл
script.log
содержит все трассировки иscript.tim
является файлом времени :Вы можете увидеть общее время выполнения с первой и последней строками файла журнала и / или суммируя время в файле времени:
В файле синхронизации второе значение - это количество следующих байтов в соответствующем файле журнала. Это дает вам возможность воспроизводить файл журнала опционально с коэффициентом ускорения :
или
или
Отображение времени и команд бок о бок тоже немного сложнее:
Тесты и заключение
Чтобы провести тесты, я загрузил второй образец в bash complex hello world , выполнение этого скрипта на моем хосте занимает около 0,72 секунды.
Я добавил вверху скрипта одно из:
по
elap.bash
функциипо
set -x
иPS4
by
set -x
и начальная вилка для длинной команды execпо
script
(иset +x
)раз
И сравните время выполнения (на моем хосте):
Выходы
по
elap.bash
функциипо
set -x
иPS4
by
set -x
и начальная вилка для длинной команды exec (и мой второйpaste
пример скрипта)по
strace
по
script
Вывод
Хорошо! Если мой чистый bash быстрее, чем разветвление для каждой команды , мой чистый bash подразумевает некоторые операции для каждой команды.
Способ выделения независимого процесса для регистрации и хранения явно более эффективен.
strace
интересный способ, более подробный, но трудный для чтения.script
, сscriptreplay
коэффициентом ускорения и тоже очень хороши, не такой точности, поскольку это основано на обмене консолью вместо выполнения процесса, но очень легкое и эффективное (не та же цель, не то же использование).Наконец, я думаю, что более эффективным с точки зрения читаемости и производительности является
set + 1 fork
первый из этого ответа, но в порядке, в зависимости от конкретного случая я иногда используюstrace
и / илиscript
тоже.источник
exec {BASH_XTRACEFD}>
вместоexec 3>&2 2>
этого заполнить файл журнала только выходными данными журнала трассировки, а не другими выходными данными stderr.script.sh
я могу просто делатьbash -c "exec {BASH_XTRACEFD}> >(tee trace.log | sed -u 's/^.*$//' | date -f - +%s.%N > timing.log); set -x; . script.sh
и получать данные профилирования без измененияscript.sh
. Когда не требуется субсекундная точность, мне нравится,bash -c "exec {BASH_XTRACEFD}>trace.log; set -x; PS4='+\t'; . script.sh
когда каждая строка трассировки маркируется со второй точностью и без разветвления до даты (низкие накладные расходы).Часто помогает отслеживать системные вызовы
Из руководства:
-c Подсчитывать время, количество вызовов и ошибок для каждого системного вызова и сообщать сводку при выходе из программы.
-f Отслеживать дочерние процессы ...
Это не совсем то, что вам нужно, и то, что покажет вам линейно-ориентированный профилировщик, но обычно он помогает находить горячие точки.
источник
Вы можете посмотреть
trap
команду с условием DEBUG . Есть способ установить команды, которые будут выполняться вместе с вашими командами. См. Примечания к ответу.источник
help trap
: «Если SIGNAL_SPEC имеет значение DEBUG, ARG выполняется перед каждой простой командой». В Bash 3.2 написано «после». Это опечатка. Начиная с Bash 2.05b, он работал раньше. Ссылка : «В этом документе подробно описаны изменения между этой версией, bash-2.05b-alpha1, и предыдущей версией, bash-2.05a-release. ... 3. Новые возможности в Bash ... w. Ловушка DEBUG теперь запускать перед простыми командами, ((...)) командами, [[...]] условными командами и для ((...)) циклов. " Тестирование в каждой версии подтверждает, что это было раньше .Time, xtrace, bash -x
set -x
иset+x
( http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html ) остаются традиционным способом отладки скрипта.Тем не менее, чтобы расширить наш кругозор, можно проверить некоторую систему для отладки и профилирования, доступную для обычных программ Linux [здесь один из списков] , например, это должно привести к полезной системе, основанной на valgrind, особенно для отладки памяти или sysprof для профилирования вся система:
Для sysprof:
А после выбрать интересующую вас ветку подпроцессов.
Для Valgrind:
Имея еще немного тренажерного зала, кажется, можно сделать видимыми для Valgrind некоторые программы, которые мы обычно устанавливаем из двоичного кода (например, OpenOffice ).
Можно прочитать из FAQ valgrind ,
Valgrind
который профилирует дочерние процессы, если явно запрошено.Он сделает это с включенной опцией
Дополнительные ссылки:
источник
Это сообщение от Alan Hargreaves описывает метод профилирования Bourne сценария оболочки поставщика DTrace. Насколько мне известно, это работает с Solaris и OpenSolaris (см. / Bin / sh DTrace Provider ).
Итак, учитывая следующий сценарий dtrace (
sh_flowtime.d
в GH на основе оригинала ):вы можете отслеживать выполнение функции, включая дельта-времена.
Пример вывода:
Затем, используя
sort -nrk7
команду, вы можете отсортировать вывод, чтобы показать наиболее ресурсоемкие вызовы.Мне не известны какие-либо зонды поставщиков, доступные для других оболочек, поэтому проведите небольшое исследование (поиск GitHub?), Или, если вы хотите потратить некоторое время, вы можете написать такое на основе существующего примера sh : (см .: Как активировать sh Провайдер DTrace? ).
источник