web-dev-qa-db-ja.com

Rubyでミリ秒単位で操作の時間を計る方法は?

特定の関数が使用するミリ秒数を把握したいと思っています。だから私は高くも低くも見えましたが、ミリ秒の精度でRubyで時間を取得する方法を見つけることができませんでした。

これどうやってやるの?ほとんどのプログラミング言語では

start = now.milliseconds
myfunction()
end = now.milliseconds
time = end - start
74
Earlz

RubyのTimeクラスを使用できます。例えば:

t1 = Time.now
# processing...
t2 = Time.now
delta = t2 - t1 # in seconds

現在、deltafloatオブジェクトであり、クラスが提供するのと同じくらい細かい結果を得ることができます。

85
ezpz

組み込みのBenchmark.measure関数も使用できます。

require "benchmark"
puts(Benchmark.measure { sleep 0.5 })

プリント:

0.000000   0.000000   0.000000 (  0.501134)
55

_Time.now_(実時間を返す)をベースラインとして使用すると、予期しない動作を引き起こす可能性のあるいくつかの問題があります。これは、壁時計の時刻が、挿入されたうるう秒や time slewing などの変更の影響を受けて、ローカル時刻を基準時刻に調整するために発生します。

がある場合測定中にうるう秒が挿入されると、1秒ずれます。同様に、ローカルシステムの状態に応じて、夏時間、より速いまたはより遅い実行クロック、またはクロックが時間に戻ることさえあり、負の期間やその他の多くの問題が発生する場合があります。

この問題の解決策は、異なるクロック時間を使用することです:単調なクロック。このタイプの時計には、壁時計とは異なる特性があります。これは単調に増加します。つまり、戻ることはなく、一定の割合で増加します。そのため、壁時計(つまり、壁の時計から読み取った時間)ではなく、後のタイムスタンプと比較して差異を得ることができるタイムスタンプを表します。

Rubyでは、次のようにProcess.clock_gettime(Process::CLOCK_MONOTONIC)でそのようなタイムスタンプを使用できます。

_t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# => 63988.576809828

sleep 1.5 # do some work

t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# => 63990.08359163

delta = t2 - t1
# => 1.5067818019961123
delta_in_milliseconds = delta * 1000
# => 1506.7818019961123
_

_Process.clock_gettime_ メソッドは、秒の小数部を持つ浮動小数点数としてタイムスタンプを返します。返される実際の数には、定義された意味はありません(信頼する必要があります)。ただし、次の呼び出しで確実に大きな数値が返され、値を比較することでリアルタイムの差を取得できます。

これらの属性により、このメソッドは、プログラムが最も適切な時間に失敗することなく時間差を測定するための最有力候補になります(たとえば、別のうるう秒が挿入される大New日の真夜中)。

ここで使用される_Process::CLOCK_MONOTONIC_定数は、最新のすべてのLinux、BSD、macOSシステム、およびWindows用のLinuxサブシステムで使用できます。 (私の知る限りでは)「生の」Windowsシステムではまだ利用できません。そこでは、_Process.clock_gettime_の代わりに GetTickCount システムコールを使用できます。これは、Windowsでミリ秒単位のタイマー値も返します。

17
Holger Just

ベンチマークを実行するには、ベンチマークモジュールをご覧ください。ただし、迅速でダーティなタイミング方法として、次のようなものを使用できます。

def time
  now = Time.now.to_f
  yield
  endd = Time.now.to_f
  endd - now
end

To_iとは異なり、秒に切り捨てられないTime.now.to_fの使用に注意してください。

13
sepp2k

Time.now.to_fを使用する

1
sutch

また、任意のコードブロックを記録する単純な関数を作成できます。

def log_time
  start_at = Time.now

  yield if block_given?

  execution_time = (Time.now - start_at).round(2)
  puts "Execution time: #{execution_time}s"
end

log_time { sleep(2.545) } # Execution time: 2.55s
1
Slava Zharkov

absolute_time gemはBenchmarkのドロップイン代替品ですが、ネイティブの命令を使用してはるかに正確にしています。

1
user246672

Rubyメソッド(インスタンスまたはクラス)- https://github.com/igorkasyanchuk/benchmark_methods )をプロファイルできるgemがあります。

このようなコードはもうありません:

t = Time.now
user.calculate_report
puts Time.now - t

できるようになりました:

benchmark :calculate_report # in class

そして、あなたのメソッドを呼び出すだけです

user.calculate_report
0
Igor Kasyanchuk

の用法 Time.now.to_i 1970/01/01から渡された2番目を返します。あなたができることを知っている

date1 = Time.now.to_f
date2 = Time.now.to_f
diff = date2 - date1

これにより、差があります秒単位大きさ。 ミリ秒で必要な場合は、コードに追加するだけです

diff = diff * 1000
0
MARC.RS

使用する場合

date = Time.now.to_i

時間を秒単位で取得しています。これは、コードの小さな塊をタイミングする場合は特に正確ではありません。

0
user3401815