On Jul 14, 2012, at 2:15 PM, Matt Jones wrote:
>
> On Jul 12, 2012, at 7:44 PM, Raphael Sofaer wrote:
>
>> Hi Matt, Vivek,
>>
>> Here's some more information. The app is running in production mode,
>> although I'd like it to be a reasonable speed in dev mode also, for
>> development. Dev mode now is up to twice as slow. There's tons of free
>> memory and cpu on the machine. Rails and hobo versions:
>> rails (3.0.5)
>> hobo (1.3.0)
>
> Just to verify, which Ruby are you running on? (1.8.6 / 1.8.7 / 1.9.2)
>
> Some preliminary profiling on 1.9.2 is turning up (bizarrely) Array#to_s as a
> major time sink. This may be a side-effect of changes in 1.9 (it used to just
> glue all the strings together, now it adds brackets + inspects the strings).
> More as this develops.
>
> --Matt Jones
>
Replying to my own message - Array#to_s is *part* of the problem (not helped by
debugging code I left in - ugh) but another (unexpected) time-sink is actually
method_missing on NilClass. Turns out, this code:
a, b = nil
tries to call to_ary on nil, builds a NoMethodError, and then *silently
discards it*. I'm seeing something like 12% of the total runtime soaking into
this utterly useless behavior. Disabling whiny nils shifts where the time goes,
but doesn't stop it; there's something obscure going on in Ruby's guts that's
causing this.
In the meantime, the truly adventurous can try changing the definition of
new_context (in template_environment.rb) from this:
def new_context
ctx = [ @_this, @_this_parent, @_this_field, @_this_type,
@_form_field_path, @_form_field_paths_by_object ]
@_this_type = nil
res = nil
outer_res = @view.with_output_buffer { res = yield }
Rails.logger.error("new_context: #{caller.first}") if !outer_res.blank?
&& outer_res.to_s != res.to_s
@_this, @_this_parent, @_this_field, @_this_type, @_form_field_path,
@_form_field_paths_by_object = ctx
res.to_s
end
to this:
def new_context
ctx = [ @_this, @_this_parent, @_this_field, @_this_type,
@_form_field_path, @_form_field_paths_by_object ]
@_this_type = nil
res = nil
outer_res = @view.with_output_buffer { res = yield }
@_this, @_this_parent, @_this_field, @_this_type, @_form_field_path,
@_form_field_paths_by_object = ctx
if res.is_a?(Array)
res.join('')
else
res.to_s
end
end
This restores the ruby1.8 behavior of Array#to_s, and saves a considerable
amount of time. However, I'm not sure it's the right fix, since the return
value of the old version of new_context was *clearly* nonsense for the cases it
fixes (it returned a formatted array, like this: "['something',
'some_other_thing', 'bleh']") so the join may not be needed at all, since those
cases never turn up in the displayed HTML.
Fun fact: the ERB created by DRYML is sufficiently weird (especially with all
the new_context recursion) that it tends to confuse ruby-prof - turning on
memory profiling causes it to claim (sometimes) that 18014398505397860 bytes
have been allocated...
More updates soon.
--Matt Jones
--
You received this message because you are subscribed to the Google Groups "Hobo
Users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/hobousers?hl=en.