1

セルロイドのeveryメソッドを使用してマイクロ秒ごとにブロックを実行していますが、小数点を指定しても常にブロックを毎秒呼び出すようです。

interval = 1.0 / 2.0

every interval do
  puts "*"*80
  puts "Time: #{Time.now}"
  puts "*"*80
end

これが 0.5 秒ごとに呼び出されることを期待します。ただし、1秒ごとに呼び出されます。

助言がありますか?

4

1 に答える 1

4

セルロイドを使用すると、分数秒の解像度を得ることができます。

Celluloid は、Timers gem を使用して を管理しますevery。これは、適切な浮動小数点時間の計算を行い、rubysleepは妥当な 1 秒未満の解像度を持っています。

次のコードは完全に機能します。

class Bob
  include Celluloid
  def fred
    every 0.5 do
      puts Time.now.strftime "%M:%S.%N"
    end
  end
end

Bob.new.fred

そして、次の出力が生成されます。

22:51.299923000
22:51.801311000
22:52.302229000
22:52.803512000
22:53.304800000
22:53.805759000
22:54.307003000
22:54.808279000
22:55.309358000
22:55.810017000

ご覧のとおり、これは完全ではありませんが、ほとんどの目的には十分に近いものです。

異なる結果が表示される場合は、指定したブロックでコードにかかる時間、everyまたは他のタイマーが実行されてその特定のタイマーが不足していることが原因である可能性があります。可能な限り状況を単純化し、ゆっくりとパーツを追加して、速度低下が発生している場所を特定することで、それにアプローチします。

マイクロ秒の解像度に関しては、自明ではないコードで確実にそこまで下げることは期待できないと思います。

些細な例:

def bob
  puts Time.now.strftime "%M:%S.%N"
  sleep 1.0e-6
  puts Time.now.strftime "%M:%S.%N"
end

プロデュース:

31:07.373858000
31:07.373936000


31:08.430110000
31:08.430183000


31:09.062000000
31:09.062079000


31:09.638078000
31:09.638156000

ご覧のとおり、単純な行だけを実行している私のマシンのベース Ruby バージョンだけでも、IOマイクロ秒の速度が確実に得られるわけではありません。

于 2013-02-01T08:26:53.910 に答える