web-dev-qa-db-ja.com

スクリプトの実行時間を効果的に取得するにはどうすればよいですか?

スクリプトの完了時間を表示したいのですが。

私が現在していることは-

#!/bin/bash
date  ## echo the date at start
# the script contents
date  ## echo the date at end

これは、スクリプトの開始と終了の時間です。プロセッサ時間/ IO時間などのようなきめの細かい出力を表示することは可能ですか?

392
mtk

スクリプトを呼び出すときにtimeを使用するだけです。

time yourscript.sh
506
Trudbert

timeがオプションでない場合、

start=`date +%s`
stuff
end=`date +%s`

runtime=$((end-start))
204
Rob Bos

スクリプトを終了するときに、引数なしで times を呼び出すだけです。

kshまたはzshを使用すると、代わりにtimeを使用することもできます。 zshを使用すると、timeusersystemCPU時間。

スクリプトの終了ステータスを保持するには、次のようにします。

ret=$?; times; exit "$ret"

または、EXITにトラップを追加することもできます。

trap times EXIT

このように、シェルが終了し、終了ステータスが保持されるたびに時間が呼び出されます。

$ bash -c 'trap times EXIT; : {1..1000000}'
0m0.932s 0m0.028s
0m0.000s 0m0.000s
$ zsh -c 'trap time EXIT; : {1..1000000}'
Shell  0.67s user 0.01s system 100% cpu 0.677 total
children  0.00s user 0.00s system 0% cpu 0.677 total

また、bashksh、およびzshのすべてに、毎秒自動的にインクリメントされる$SECONDS特殊変数があることに注意してください。 zshksh93の両方で、その変数を浮動小数点にして(typeset -F SECONDSを使用)、精度を上げることもできます。これは実時間であり、CPU時間ではありません。

77

私はバンドワゴンに少し遅れましたが、他の人が検索によってこのスレッドに偶然出くわした場合に備えて、(1秒未満の精度で)私の解決策を投稿したいと思いました。出力は、日、時間、分、最後に秒の形式です。

res1=$(date +%s.%N)

# do stuff in here

res2=$(date +%s.%N)
dt=$(echo "$res2 - $res1" | bc)
dd=$(echo "$dt/86400" | bc)
dt2=$(echo "$dt-86400*$dd" | bc)
dh=$(echo "$dt2/3600" | bc)
dt3=$(echo "$dt2-3600*$dh" | bc)
dm=$(echo "$dt3/60" | bc)
ds=$(echo "$dt3-60*$dm" | bc)

LC_NUMERIC=C printf "Total runtime: %d:%02d:%02d:%02.4f\n" $dd $dh $dm $ds

誰かがこれが役に立つことを願っています!

32
jwchew

bashの私の方法:

# Reset BASH time counter
SECONDS=0
    # 
    # do stuff
    # 
ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec"
23
Mark

この質問はかなり古いですが、私の好きな方法を見つけようとしたときに、このスレッドは高くなりました...そして誰もそれを言及しなかったことに驚いています:

perf stat -r 10 -B sleep 1

「perf」は、「tools/perf」の下のカーネルに含まれているパフォーマンス分析ツールであり、多くの場合、個別のパッケージ(CentOSでは「perf」、Debian/Ubuntuでは「linux-tools」)としてインストールできます。 The Linux Kernal perf Wiki には、それに関する多くの情報があります。

「perf stat」を実行すると、最後の平均実行時間など、かなりの詳細が表示されます。

1.002248382 seconds time elapsed                   ( +-  0.01% )
8
Zaahid
#!/bin/bash
start=$(date +%s.%N)

# HERE BE CODE

end=$(date +%s.%N)    
runtime=$(python -c "print(${end} - ${start})")

echo "Runtime was $runtime"

はい、これはPythonを呼び出しますが、これを使用できるのであれば、これは非常に簡潔で簡潔なソリューションです。

6
Alex

時間を測定するコマンドの前に追加できる小さなシェル関数:

tm() {
  local start=$(date +%s)
  $@
  local exit_code=$?
  echo >&2 "took ~$(($(date +%s)-${start})) seconds. exited with ${exit_code}"
  return $exit_code
}

次に、スクリプトで使用するか、コマンドラインで次のように使用します。

tm the_original_command with all its parameters
5
Evgeny

個人的には、すべてのスクリプトコードを次のような「メイン」関数にラップするのが好きです。

main () {
 echo running ...
}

# stuff ...

# calling the function at the very end of the script
time main

このシナリオでtimeコマンドを使用するのがいかに簡単であるかに注意してください。明らかに、スクリプトの解析時間を含めて正確な時間を測定しているわけではありませんが、ほとんどの状況では十分正確であると思います。

5
LeZuse

only bashを使用すると、シェルスクリプトの一部の持続時間(またはスクリプト全体の経過時間)を測定およびcalculateすることもできます。

start=$SECONDS

... # do time consuming stuff

end=$SECONDS

違いを出力することもできます:

echo "duration: $((end-start)) seconds."

増分期間のみが必要な場合は、次のようにします。

echo "duration: $((SECONDS-start)) seconds elapsed.."

期間を変数に格納することもできます。

let diff=end-start
3
gauteh

これはアレックスの答えのバリエーションです。気になるのは分と秒だけですが、フォーマットを変えてほしかったです。だから私はこれをしました:

start=$(date +%s)
end=$(date +%s)
runtime=$(python -c "print '%u:%02u' % ((${end} - ${start})/60, (${end} - ${start})%60)")
3
mpontillo
#!/bin/csh
#PBS -q glean
#PBS -l nodes=1:ppn=1
#PBS -l walltime=10:00:00
#PBS -o a.log
#PBS -e a.err
#PBS -V
#PBS -M [email protected]
#PBS -m abe
#PBS -A k4zhang-group
START=$(date +%s)
for i in {1..1000000}
do
echo 1
done
END=$(date +%s)
DIFF=$(echo "$END - $START" | bc)
echo "It takes DIFF=$DIFF seconds to complete this task..."
3
Shicheng Guo

SECONDSに基づくタイミング関数は、第2レベルの粒度のみに制限され、外部コマンドを使用しません。

time_it() {
  local start=$SECONDS ts ec
  printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
  printf '%s\n' "$ts Starting $*"
  "$@"; ec=$?
  printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
  printf '%s\n' "$ts Finished $*; elapsed = $((SECONDS-start)) seconds"
  # make sure to return the exit code of the command so that the caller can use it
  return "$ec"
}

例えば:

time_it sleep 5

与える

2019-03-30_17:24:37 Starting sleep 5 2019-03-30_17:24:42 Finished
sleep 5; elapsed = 5 seconds
2
codeforester
#!/bin/bash
begin=$(date +"%s")

Script

termin=$(date +"%s")
difftimelps=$(($termin-$begin))
echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."
1
Arun Binoy

Bashの場合、内部$SECONDS変数を使用します。ここにデモがあります:

この場合、printf関数を使用して丸めているため、dt_min0.01666666666...(1秒=その分)から0.017に丸められることに注意してください。以下のsleep 1;の部分は、スクリプトを呼び出して実行する場所ですが、このデモのために、代わりに1秒間スリープしています。

start=$SECONDS; sleep 1; end=$SECONDS; dt_sec=$(( end - start )); dt_min=$(printf %.3f $(echo "$dt_sec/60" | bc -l)); echo "dt_sec = $dt_sec; dt_min = $dt_min"
dt_sec = 1; dt_min = 0.017

関連:

0
Gabriel Staples