From: Robert Klemme Date: 2011-03-16T21:08:42+09:00 Subject: Re: NoMethodError#message takes very long On Wed, Mar 16, 2011 at 7:24 AM, Eric Hodel wrote: > On Mar 15, 2011, at 8:25 PM, Adiel Mittmann wrote: > >> Hello. >> >> I've been noticing a problem for a while in a larger application and today I >> produced a minimal example, given below. When a method is not found, Sinatra >> calls NoMethodError#message to display a nice error message, but that is taking >> VERY long. >> >> >> require 'sinatra' >> require 'nokogiri' >> get '/' do >>  @xml = Nokogiri::XML(File.new('baz.xml', 'rb').read()) >>  foo() >>  'hello' >> end >> >> >> The file 'baz.xml' can be just a simple file, like a root element containing >> some thousands of elements. The number of elements is important because, oddly >> enough, the time taken for the message to be displayed is proportional to the >> size of the XML file. In my system, with a 3.7 MB file this program takes almost >> 13 seconds to print the message, but in a larger application the message takes a >> few minutes to appear. > > Let me see if I have this straight: > > If baz.xml is empty it is fast > If baz.xml is large it is slow > > If this is true it is because it takes time to parse the XML file before it gets to foo and discovers that there is no method foo. > > Ruby does not know that foo does not exist until you try to call it. Additional remarks: the file is not properly closed and reading the whole file in one go is probably also not a good solution. I'd rather require 'sinatra' require 'nokogiri' get '/' do @xml = File.open('baz.xml', 'rb') {|io| Nokogiri::XML(io)} foo() 'hello' end Note, the fact that you read in a large file as one String can actually be related to your slowness because it might case GC overhead. Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/