Rubyで経過時間をミリ秒単位で取得するにはどうすればよいですか?


98

Timeから取得したオブジェクトがある場合:

Time.now

その後、同じ行で別のオブジェクトをインスタンス化します。経過したミリ秒数を確認するにはどうすればよいですか?2番目のオブジェクトは、同じ分、次の数分または数時間にわたって作成されます。

回答:


133

すでに述べたように、Time数値(または浮動小数点)値であるかのようにオブジェクトを操作できます。これらの操作により、簡単に変換できる2番目の解像度が得られます。

例えば:

def time_diff_milli(start, finish)
   (finish - start) * 1000.0
end

t1 = Time.now
# arbitrary elapsed time
t2 = Time.now

msecs = time_diff_milli t1, t2

それを切り捨てるかどうかを決定する必要があります。


2
to_iを追加すると、それは整数として得られます。例:((finish-start)* 1000.0).to_i
Travis Reeder

finish.to_f - start.to_f
2014年

1
finish - start浮動小数点を生成します。.to_f冗長になります。
ezpz 14年

5
レールまたはアクティブサポートを使用している場合は、#in_millisecondsメソッドを使用して同じ変換を実行できます(t2 - t1).in_milliseconds
Nathan Hanna

58

次のようにして、上記のソリューションに構文シュガーを少し追加できます。

class Time
  def to_ms
    (self.to_f * 1000.0).to_i
  end
end

start_time = Time.now
sleep(3)
end_time = Time.now
elapsed_time = end_time.to_ms - start_time.to_ms  # => 3004

31

私は答えが間違って選択されていると思います、その方法はミリ秒ではなく秒を与えます。

t = Time.now.t­o_f
=> 1382471965.146

ここでは、浮動小数点値がミリ秒であると仮定します


1
選ばれた答えは正しいです。加算または減算を使用Time.nowすると、時間は小数点の前の秒と小数点の後のナノ秒までの浮動小数点値として扱われます(ただし、nsecは完全に正確ではない場合があります)。したがって、その値を掛けると1000.0ミリ秒になります。
dfherr 2017年

はい、しかし「Time.now」だけを与えるのは不正確であり、質問に正確に答えることはできません。
LowFieldTheory

12

ミリ秒単位で時間を取得するには.round(3)、を追加する方がよいため、場合によってはより正確になります。

puts Time.now.to_f # => 1453402722.577573

(Time.now.to_f.round(3)*1000).to_i  # => 1453402722578

9

ezpzの答えはほぼ完璧ですが、もう少し追加できるといいのですが。

Geoはミリ秒単位の時間について尋ねました。これは整数の量のように聞こえ、私は浮動小数点の土地を迂回することはしません。したがって、私のアプローチは:

irb(main):038:0> t8 = Time.now
=> Sun Nov 01 15:18:04 +0100 2009
irb(main):039:0> t9 = Time.now
=> Sun Nov 01 15:18:18 +0100 2009
irb(main):040:0> dif = t9 - t8
=> 13.940166
irb(main):041:0> (1000 * dif).to_i
=> 13940

整数1000を掛けると、小数が完全に保持され、少し速くなる場合もあります。

日付と時刻を処理する場合は、DateTimeクラスを使用する必要がある場合があります。これは同様に機能しますが、変換係数は24 * 3600 * 1000 = 86400000です。

DateTimeのstrptime関数とstrftime関数は、日付/時刻文字列(ログへ/からのログなど)の解析とフォーマットに非常に役立つことがわかりました。知っておくと便利なのは:

  • これらの関数(%H、%M、%S、...)のフォーマット文字は、Unix / LinuxシステムにあるC関数とほとんど同じです。そして

  • さらにいくつかあります:特に、%Lはミリ秒を実行します!


知っておきたい!ありがとうunknown:)
Geo

1
とにかく、%LはRuby 1.9にのみ存在します;)
Rafa de Castro


6

Time.now.to_fは役立ちますが、秒数を返します。

一般的に、ベンチマークで作業するとき、私は:

  • 現在時刻を変数に入れます。
  • テストするブロックを挿入します。
  • 変数に現在の時刻を入れ、前の現在の時刻の値を減算します。

それは非常に単純なプロセスなので、あなたが本当にこれを求めていたのかわかりません...


6

%L ルビでミリ秒を与える

require 'time'
puts Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L")

または

puts Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")

ミリ秒単位の現在のタイムスタンプが表示されます。


これは、経過時間を取得する方法については述べていません。
ロバート

4

答えは次のようなものです:

t_start = Time.now
# time-consuming operation
t_end = Time.now

milliseconds = (t_start - t_end) * 1000.0

しかし Time.nowアプローチは不正確になるリスクがあります。Luca Guidiがこの投稿を見つけました:

https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/

システムクロックは常に変動し、順方向にしか移動しません。経過時間の計算がそれに基づいている場合は、計算エラーまたは機能停止に遭遇する可能性が非常に高くなります。

そのため、Process.clock_gettime代わりに使用することをお勧めします。何かのようなもの:

def measure_time
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  yield
  end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  elapsed_time = end_time - start_time
  elapsed_time.round(3)
end

例:

elapsed = measure_time do
    # your time-consuming task here:
    sleep 2.2321
end

=> 2.232

3

2番目の時間から最初のTime.nowを減算してみてください。そのようです:

a = Time.now
sleep(3)
puts Time.now - a # about 3.0

これにより、2つの時間の間の秒の浮動小数点数(および、ミリ秒)が得られます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.