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 tod=
ay I
>> produced a minimal example, given below. When a method is not found, Sin=
atra
>> calls NoMethodError#message to display a nice error message, but that is=
taking
>> VERY long.
>>
>> <snip>
>> require 'sinatra'
>> require 'nokogiri'
>> get '/' do
>> =A0@xml =3D Nokogiri::XML(File.new('baz.xml', 'rb').read())
>> =A0foo()
>> =A0'hello'
>> end
>> </snip>
>>
>> The file 'baz.xml' can be just a simple file, like a root element contai=
ning
>> some thousands of elements. The number of elements is important because,=
oddly
>> enough, the time taken for the message to be displayed is proportional t=
o the
>> size of the XML file. In my system, with a 3.7 MB file this program take=
s 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 =3D 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
--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/