プログラムの実行時間を測定して変数に保存する方法

プログラムの実行時間を測定して変数に保存する方法

timeBash(v4 +)スクリプトの特定の操作にかかる時間を確認するために、コマンドの出力を「別々に」解析して(最終的に)let VARNAME=...Bash変数()にキャプチャしたいと思います。

time -f '%e' ...私は(または組み込みのBashのために)使用していますが、command time -f '%e' ...実行されたコマンドの出力をリダイレクトしたので、コマンドの出力をキャプチャする方法がわかりませんtime。基本的にここで問題は別々の出力timeコマンド実行の出力です。

私が望むもの特徴開始コマンドと完了の間の秒数を計算します。time必ずしもコマンドや対応する組み込みコマンドである必要はありません。


編集する:以下の2つの有用な答えに基づいて、2つの説明を追加したいと思います。

  1. 実行されたコマンドの出力を破棄したくありませんが、それがstdoutで終わってもstderrで終わっても構いません。
  2. 私は間接的なアプローチ(つまり、出力を中間ファイルに保存する代わりに直接キャプチャする)よりも直接的なアプローチを好みます。

これまで使用されているソリューションは、date私が望むソリューションに近いです。

答え1

出力をtimevarに入れるには、次のコマンドを使用します。

usr@srv $ mytime="$(time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$mytime"

real    0m0.006s
user    0m0.001s
sys     0m0.005s

utimeなどの単一の時間タイプのみを要求できます。

usr@srv $ utime="$( TIMEFORMAT='%lU';time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$utime"
0m0.000s

時間を取得するには、次を使用してdate +%s.%N実行前後の時間を取得し、差を計算することもできます。

START=$(date +%s.%N)
command
END=$(date +%s.%N)
DIFF=$(echo "$END - $START" | bc)
# echo $DIFF

答え2

に属し、1秒未満の精度が必要でないbash場合は、呼び出しを完全にスキップして追加のプロセスを作成せず、結合された出力を分離することなく、キャプチャおよび解析を行うことなくこれを実行できます。すべてのコマンドの出力:shdate

# SECONDS is a bash special variable that returns the seconds since set.
SECONDS=0
mycmd <infile >outfile 2>errfile
DURATION_IN_SECONDS=$SECONDS
# Now `$DURATION_IN_SECONDS` is the number of seconds.

答え3

Bashでは、構成の出力はtime標準エラーに移動し、影響を受けるパイプの標準エラーをリダイレクトできます。それでは、出力とエラーストリームを作成するコマンドから始めましょうsh -c 'echo out; echo 1>&2 err'。コマンドのエラー・ストリームを出力と混同しないように、コマンドtimeのエラー・ストリームを一時的に別のファイル記述子に移動できます。

{ time -p sh -c 'echo out; echo 1>&2 err' 2>&3; }

outこれにより、fd 1、errfd 3、およびfd 2に時間が記録されます。

{ time -p sh -c 'echo out; echo 1>&2 err' 2>&3; } \
    3> >(sed 's/^/ERR:/') 2> >(sed 's/^/TIME:/') > >(sed 's/^/OUT:/')

fd 2の時間とfd 3の時間がもっと楽しい場合は、errそれを交換してください。これは、2つのファイル記述子を交換する直接的な方法がないために問題になります。

{ { { time -p sh -c 'echo out; echo 1>&2 err' 2>&3; } 3>&2 2>&4; } 4>&3; } 3> >(sed 's/^/TIME:/') 2> >(sed 's/^/ERR:/') > >(sed 's/^/OUT:/')

これはコマンド出力を後処理する方法を示していますが、コマンド出力とタイミングをキャプチャするにはもっと作業が必要です。一時ファイルを使用することは1つの解決策です。実際、これはコマンドの標準エラーと標準出力をキャプチャする必要がある場合に信頼できる唯一のソリューションです。しかし、それ以上の出力全体をキャプチャし、time予測可能な形式があるという事実を利用することができます(time -p使用する場合)。POSIX形式またはbash固有のTIMEFORMAT変数)。

nl=$'\n'
output=$(TIMEFORMAT='%R %U %S %P'; mycommand)
set ${output##*$nl}; real_time=$1 user_time=$2 system_time=$3 cpu_percent=$4
output=${output%$nl*}

ウォールクロック時間にのみ興味がある場合は、date前後を実行するのが簡単な解決策です(外部コマンドをロードするのにかかる追加の時間によって精度がわずかに低下する場合)。

答え4

OSXで以前の回答をすべて合わせたとき

ProductName:    Mac OS X
ProductVersion: 10.11.6
BuildVersion:   15G31+

あなたはこれを行うことができます

microtime() {
    python -c 'import time; print time.time()'
}
compute() {
    local START=$(microtime)
    #$1 is command $2 are args
    local END=$(microtime)
    DIFF=$(echo "$END - $START" | bc)
    echo "$1\t$2\t$DIFF"
}

関連情報