TimeoutX 0.2.0 を公開しました

今更感漂う過去の遺物がHDDの奥底から発掘されたのを記念してTimeoutX 0.2.0を公開致しました。

TimeoutXとは激烈に速いtimeout関数を提供するだけのライブラリです。ちなみに最初の公開は2002年。あまりにキワモノなのでどこかの闇に失なわれてもう五年。時代の流れにあがなうようにgem化することでついにいつでもどこでもTimeoutXが使えるようになりました。

timeout関数が速いとはどういうことよ?と思う方もいらっしゃるでしょうから分かり易いベンチマーク結果を載せておきます。まずベンチマークは以下のようになります。

n = 100000
Benchmark.bmbm(10) do |x|
  x.report("Timeout") { 1.upto(n) do ; Timeout.timeout(1){true}; end }
  x.report("TimeoutX") { 1.upto(n) do ; TimeoutX.timeout(1){true}; end }
end

この実行結果は1.8.6の場合以下のようになります。

Rehearsal ---------------------------------------------
Timeout     5.960000   0.460000   6.420000 (  6.521520)
TimeoutX    0.780000   0.050000   0.830000 (  0.851778)
------------------------------------ total: 7.250000sec

                user     system      total        real
Timeout     5.650000   0.790000   6.440000 (  6.516992)
TimeoutX    0.760000   0.080000   0.840000 (  0.863438)

おお、激烈に速い!という程でもない気もしますが、まぁ10万回も呼び出せばさすがに体感出来るくらいには違います。そういうわけですからtimeout関数を10万回も呼び出しちゃいたいような奇特な方は是非ともTimeoutXをご使用下さい。ご利用にはgemを使うのが便利だと思います。

sudo gem install timeoutx


一応、何故このような差が出るのかを解説しておきます。Ruby標準添付のtimeout.rbはtimeout関数を一回呼び出す毎に新たなスレッドをひとつ作成します。よって上のように10万回連続で呼び出すと10万ものスレッドを作成してしまうわけです。スレッド作成のコストはちょこっとありますので、これを10万回も繰り返しますとさすがにそれなりに時間がかかります。TimeoutXではこのスレッド生成を避けるため、timeout専用のスレッドをひとつ作成し、そこでタイムアウト処理を行なっています。簡単に言うと、手抜き!

TimeoutXを作った歴史的な経緯は元々Webrickの高速化用専用です。というか、タイムアウト処理を短時間の内に繰り返す必要のあるRubyのアプリケーションなんてそうそうあるわけないのであって。しかもWebrick(当然mongrelも)は今やtimeout.rbを使用せず独自にタイムアウト処理を実装しているため、もう使い道がありません。そういうわけで長らく闇に葬られていたのですが、先日たまたまHDDの奥底から発見しましたので、モニュメントとしてgem化した次第です。

ちなみに 1.9.0 のベンチマーク結果にちょっとびっくり。

Rehearsal ---------------------------------------------
Timeout    12.140000   2.760000  14.900000 ( 15.333607)
TimeoutX    0.490000   0.010000   0.500000 (  0.518974)
----------------------------------- total: 15.400000sec

                user     system      total        real
Timeout    11.210000   2.390000  13.600000 ( 14.337455)
TimeoutX    0.490000   0.010000   0.500000 (  0.512449)

というわけで、1.8.6よりもスレッド生成のコストが上昇しているようです。あまり1.9系の事情はよく分かっていないのですが、このことを頭の片隅に留めておこうかな、と思いました。