2010年9月7日火曜日

RubyでNoMethodError時にObject#inspectが使われている

RubyKaigi2010での関 将俊さんの発表で聞いた話。

dRubyアプリケーション(RWiki)にirbから接続した時、
メソッド名の打ち間違えをするとなんだかとても遅い。

原因は、NoMethodError時にObject#inspectが走っており、
たくさんのデータ(配列やハッシュに入った数万のオブジェクト)を抱えているオブジェクトを
見えるように印字したらそりゃ遅いよねという話だった。

ruby-1.9.2-p0 > Object.new.does_not_exist_method
NoMethodError: undefined method `does_not_exist_method' for #<Object:0x00000001088288>
 from (irb):1
 from /home/oshow/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `<main>'

ruby-1.9.2-p0 > class Object
ruby-1.9.2-p0 ?>  def inspect
ruby-1.9.2-p0 ?>    "HELLO"
ruby-1.9.2-p0 ?>  end
ruby-1.9.2-p0 ?>end
 => nil 

ruby-1.9.2-p0 > Object.new.does_not_exist_method
NoMethodError: undefined method `does_not_exist_method' for HELLO:Object
 from (irb):7
 from /home/oshow/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `<main>'

確かに、「for #<Object:0x00000001088288>」ってところが
「for HELLO」に変わった。inspectが使われているらしい。

実際にも、関さんはObject#inspectを再定義して遅くなるのを回避したそうです。
(しかたなく…らしい(笑)。発表の動画を見るとわかります)

0 件のコメント:

コメントを投稿

フォロワー