1

私が書いているフレームワークについて、(bash) コードの実行にかかる時間を測定し、経過時間を秒単位で出力したいと思います。

測定のために、私は次のことを行います。

start=$(date +%s%N)

# do something here

elapsed_time=$(($(date +%s%N) - start))

これにより、経過したナノ秒と連結された経過秒数が得られます。これを 1000000 で割ると、ミリ秒単位の時間が得られます

elapsed_time_in_ms=$(($elapsed time / 1000000))

これはすべてうまく機能しているように見えますが、実際の問題は、この形式で印刷したいということです:

12.789s

の前は.秒で、ドットの後ろは ms 値の最後の 3 桁です。

どうすればそのようなことを達成できますか?

編集

時間はおそらくあまり役​​に立たないことは承知していますが、それでもこれを実装したいと思います(たとえ見た目の理由だけであっても:-))。

編集2

同じ問題に直面している人のために:

最終的に、フォークを必要とせず、最も移植性の高いソリューションと思われる time を使用することにしました。

ここで関数itとグローバルtotal_elapsed_time変数を見て、これをどのように実装したかを確認してください。

4

4 に答える 4

4

bc次のコマンドを使用できます。

elapsed_time_in_ms=$(echo "scale=3;$elapsed_time/1000000" | bc)

基本的に、のscale後に必要な桁数を設定します.

于 2012-10-10T13:52:45.587 に答える
1

ナノ秒から最初の 3 桁の後の数字を切り取るだけです。

printf "%d.%.3ss\n" date +%S date +%N# date を 1 回だけ実行するのはそれほど賢明ではないかもしれません。

-- 数字の後にドットを出力し、次の引数を文字列として扱い、最初の 3 文字のみを出力します。

$ i=0; while [ $i -lt 9 ];do i=$((i+1)); スリープ 0.1; \
       printf "%d.%.3ss\n" `date +%S` `date +%N` ;完了
33.917秒
34.025秒
34.133秒
34.240秒
34.348秒
34.457秒
34.566秒
34.674秒
34.784秒
于 2012-10-11T05:11:38.177 に答える
1

これは、シェル パラメーター展開を使用するか、printf. たとえば、次の 2 つのシーケンスを次々に実行する1349883230.7151349883230.721、1 回の実行で出力さ1349884003.0251349884003.032、別の実行で出力されます。(%N日付形式は先行ゼロで埋められます。)

  s=$(date +%s.%N); s=${s%??????}; echo $s
  t=$(printf "%20.3f" $(date +%s.%N)); echo $t

パターン マッチングの man bash で述べたように、特殊なパターン文字?は任意の 1 文字に一致します。パラメータ展開で述べたように、フォーム ${parameter%word} は一致するサフィックス パターンを削除します。 (「%%」の場合) 削除されました。」

于 2012-10-10T15:41:29.217 に答える
1

bc時間がかかる暗黙のフォークを使用するので、私はこの純粋な bashソリューションを好みます。

start=$(date +%s%N);sleep 1.1;elapsed_time=$(($(date +%s%N) - start))
_Z9=000000000
[ ${#elapsed_time} -lt 9 ] && \
    elapsed_time=${_Z9:0:9-${#elapsed_time}}$elapsed_time;
printf "%.3fs\n" ${elapsed_time:0:${#elapsed_time}-9
     }.${elapsed_time:${#elapsed_time}-9}

印刷:

1.107s

そのようなことのために、仕事をすばやく行う小さなbash ソース ファイルを作成しました。

/proc/timer_listLinux 、またはLinux で使用する/proc/uptimedate +%s%n、他のシステムで十分にテストされていません (フィードバックは大歓迎です;)。

2 つのカウンター (呼び出しごとに 1 つ、全体的なカウンターとして 1 つ) を使用し、いくつかの引数を受け入れます (コメントを読んでください)。

. elap.bash
elap -R ; for i in {1..10};do sleep .1; elap Counter $i;done;elap -t total
 0.110488478 Counter 1
 0.111014783 Counter 2
 0.117158015 Counter 3
 0.112897232 Counter 4
 0.111928207 Counter 5
 0.108822248 Counter 6
 0.113464053 Counter 7
 0.117487421 Counter 8
 0.115716626 Counter 9
 0.110493433 Counter 10
 0.008513430      1.137983926 total

そして、bc役に立つかもしれません:

time echo 'scale=1000;pi=4*a(1);0'|bc -l 
0

real    0m1.590s
user    0m0.768s
sys     0m0.008s

また

elap -R;elap BC answer is: $(echo 'scale=1000;pi=4*a(1);0'|bc -l )
    1.539957483 BC answer is: 0

このスクリプトを使用すると、次の/proc/timer_listことが可能になります。

elap -R ; for i in {1..10};do elap Counter $i;done;elap -t total
 0.001299574 Counter 1
 0.001574097 Counter 2
 0.005771637 Counter 3
 0.001428803 Counter 4
 0.010423721 Counter 5
 0.004037965 Counter 6
 0.001392464 Counter 7
 0.008092812 Counter 8
 0.001634280 Counter 9
 0.001365652 Counter 10
 0.008201473      0.045222478 total

/proc にアクセスできない同じスクリプトで、 fork を使用してdate +%s%N次のように指定します。

elap -R ; for i in {1..10};do elap Counter $i;done;elap -t total
 0.012148259 Counter 1
 0.013415551 Counter 2
 0.008279329 Counter 3
 0.013700332 Counter 4
 0.012837796 Counter 5
 0.015562929 Counter 6
 0.008062369 Counter 7
 0.016810494 Counter 8
 0.011537439 Counter 9
 0.009731194 Counter 10
 0.012959840      0.135045532 total

フォークにコストがあることがわかりました(この場合は 1/100 秒近く)。

さて、最後に、SO の質問の正確な形式を一致させるために、この小さなスクリプトにパッチを適用して、サンプルを次のようにすることができます。

eval "$(sed -e < elap.bash '
    /6d/{ s/6d.%/10.3f/g;p;N;
        :a;
          s/^.*\n//g;N;s/" \\\n[ \t]*"/./; p;
          s/^.*//g; N;/elaP_elap2/ba; }')"

elap -R ; for i in {1..10};do elap Counter $i;done;elap -t total
     0.001s Counter 1
     0.006s Counter 2
     0.007s Counter 3
     0.004s Counter 4
     0.003s Counter 5
     0.002s Counter 6
     0.001s Counter 7
     0.001s Counter 8
     0.006s Counter 9
     0.002s Counter 10
     0.004s      0.038s total

合計 38 秒

于 2013-01-01T13:25:45.067 に答える