ソースコマンドの実行タイミングを計る

ソースコマンドの実行タイミングを計る

.zshrc私は zsh ドットファイルの実行を改善しようとしており、サブスクリプトの実行時間を計測する必要があります。次のようなコード セクションがあります。

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 インスタンスを開始します。したがって、どちらの場合も、依存スクリプト (つまり、1 つの設定ファイルが別の設定ファイルに必要な操作を行う、または別の設定ファイルに何らかの影響を与える) のタイミングを簡単に測定する方法はありません。代わりに、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の経験はありませんのでご了承ください。

関連情報