Ruby Enterprise Edition の利点と難点を考えてみました

http://www.rubyenterpriseedition.com/

先日パッチを送りました Ruby Enterprise Edition(長いからREEと略しちゃいます) ですが、前に書いた時には利点がよく分かっていなかったので、なんとなくここでまとめておくことにします。だって"Enterprise"とか言うくらいだからなんだか凄そうじゃないですか。期待に胸ときめかせて、ざっと調べてみました。

利点

  1. みんな安心の1.8.6ベース。
  2. GC が copy on write に優しい、つまりたくさん fork する場合に有利。
  3. よく分かんないけど GC が速いそうです。

まず一点目ですが、とにかく普及している1.8.6だからいいんじゃないのか。そう思うわけです。メモリ貧乏な人にとっては1.9の方が嬉しいのですが、Enterprise な人はさすがに選択肢はないはず(とは思いませんが、きっとそういう事になっているだろうと思います)。

二点目についてですが、REEのGCは copy on write に優しい方式なのだそうです。どう優しいのかについての詳細は marktable.c をご覧下さい(ごめんなさい、まだちゃんと読んでません)。これを鵜呑みにすると、逆に言えば copy on write が関係ない時、すなわち fork なんか全然しないもんねー、という場合には大した利点はないということではないでしょうか。ていうわけだから、これ嬉しい人ってはっきり言って mongrel とかのクラスタを構成する人だけじゃないのでしょうか、と思いました。

三点目については、多分以下の記述がからくりの説明なんだと思います。

The garbage collector is now 20% faster! For every object to be marked or sweeped, the garbage collector has to find the heap that an object belongs to. Empirical evidence shows that the chance is very high that the current object belongs to the same heap as the last object’s heap. So caching the last lookup result improved performance dramatically.

http://izumi.plan99.net/blog/index.php/2008/01/14/making-ruby%E2%80%99s-garbage-collector-copy-on-write-friendly-part-7/

というわけですからマークの付け方に工夫があるようです。あるオブジェクトにマークをつける時に、それってその直前にマークを付けたオブジェクトと同じヒープに属している場合が多いよね、という経験主義的な知見を利用しているということでしょうか。では、どのくらい速いか簡単なスクリプトでテストしてみます。

require "benchmark"

def memsize(pid)
  (`ps -p #{pid} -o rss=`.strip.to_f/10.24).round/100.0
end

if GC.respond_to?(:copy_on_write_friendly=)
  # GC.copy_on_write_friendly = true
end

GC.disable

class Foo
  def initialize
    @bar = "0123456789"
  end
end

1_000_000.times { Foo.new }

Benchmark.bm do |x|
  x.report { GC.enable; GC.start }
end


puts "#{memsize($$)}Mb"

REEの結果は次のようになりました。

user system total real
0.500000 0.010000 0.510000 ( 0.594515)
128.63Mb

普通のruby(Ubuntu 8.04付属のruby 1.8.6)の結果は次のようになりました。

user system total real
0.370000 0.020000 0.390000 ( 0.432029)
128.6Mb

あれ、全然速くならない?ということは、GCの速さの秘密ってのはこういう事じゃないのかなぁ。これについて検証したい人は実際のRailsアプリで試すしてみるが良いと思います。あとメモリ使用量に関してはこの場合は予想通り誤差程度の差しかありません。

難点

  • なにせ 1.8.6 ベース(しかも patch level 114)

1.8.7が出ちゃったけど、いつどう追随するのか、プランが分かりません。杞憂かも知れませんが、その将来について微妙に不安を感じても不思議ではないと思います。1.8.7 が普及してきた頃合いを見計らってアップデートしてくれるとは思いますが保証もないのではないでしょうか。

とは言え、GCを除いたら普通のrubyのようなので、こういう難癖をつける以外には問題はないだろうとも思います。

まとめ

早い話が、普通のrubyに対してGC周りを工夫したもの、がREEの正体ではないかと思います。copy on write に優しいとのことなので mongrel クラスタを動かしてみない限り実力はよく分かりません(いずれramazeさんでやってみたいと思います)。一応各種条件での比較はサイトに載ってますので、とりあえずこちらを眺めて、ホントかなぁ、と疑っておくのが良いかと思います。

Performance and memory usage comparisons — Ruby Enterprise Edition