
Я пытаюсь улучшить выполнение моих zsh dotfiles, и мне нужно засекать время выполнения моих sub-scripts. У меня есть раздел кода, который .zshrc
выглядит так:
typeset -U config_files
config_files=($DOTFILES/**/*.zsh)
for file in ${(M)config_files}
do
source file
done
Я бы хотел сделать что-то вроде этого:
for file in ${(M)config_files}
do
\time -f %E source file
done
Но, к сожалению, я получаю такой ответ:
time: cannot run source: No such file or directory
Где я ошибаюсь?
решение1
source
это встроенная, а не внешняя команда, поэтому использование внешней команды time
для измерения времени не имеет смысла. Выполните одно из следующих действий:
TIMEFMT=%E
for file in ${(M)config_files}
do
time (source file)
done
Или:
for file in ${(M)config_files}
do
\time -f %E zsh -c 'source "$1"' zsh "$file"
done
В бывшем,подоболочка необходима, потому что:
Дополнительное примечание: встроенная функция time, применяемая к любой конструкции, которая выполняется в текущей оболочке, молча игнорируется. Поэтому, хотя синтаксически нормально помещать открывающую фигурную скобку или цикл повторения или что-то подобное сразу после ключевого слова time, вы не получите никакой статистики по времени. Вместо этого вам придется использовать скобки, чтобы принудительно вызвать подоболочку, которая затем хронометрируется.
И в последнем случае вы запускаете новый экземпляр zsh для каждого файла. Таким образом, в обоих случаях нет способа легкого хронометража зависимых скриптов (т. е. когда один файл конфигурации делает что-то, что требуется другим файлом конфигурации или как-то влияет на него). В качестве альтернативы вы можете сохранить вывод time
после каждого источника, что даст вам кумулятивный хронометраж:
TIMEFMT=%E
{time} 2> times
for file in ${(M)config_files}
do
source file
{time} 2>> times
done
Затем вы можете использовать awk
или что-то еще, чтобы получить индивидуальные тайминги:
awk 'NR != 1 {print $0 - prev} {prev = $0; getline}' times
решение2
Я посмотрел на man time
команду и отметил
Users of the bash shell need to use an explicit path in order to run
the external time command and not the shell builtin variant. On system
where time is installed in /usr/bin, the first example would become
так что я предполагаю, что вы должны предоставить путь для времени. Обратите внимание, у меня нет опыта в zsh