I have a Rails 2.3.8 app with an action that pulls a large amount of data from a database and renders it with anywhere from 300-600 partials (recursively rendering a tree-type structure). Benchmarking one request gives me response times of about 7 seconds.
I thought that upgrading my Ruby version to 1.9 from 1.8 would give me a performance gain, but as I benchmark the 1.9 version, I'm getting response times of about 9 seconds (2 seconds slower than on 1.8). This was quite surprising to me.
What factors would cause Ruby 1.9 to execute slower than Ruby 1.8?
Below is a portion of the log file.
Ruby 1.8
Rendered family_index/descendants/_fi_hover (0.5ms)
Rendered family_index/descendants/_descendant (4.6ms)
Rendered search/_search_div (0.1ms)
Rendered family_index/descendants/_fi_hover (0.7ms)
Rendered family_index/descendants/_descendant (4.7ms)
Rendered search/_search_div (0.1ms)
Rendered family_index/descendants/_fi_hover (0.5ms)
Rendered family_index/descendants/_descendant (4.5ms)
Rendered family_index/descendants/_fi_hover (0.5ms)
Rendered family_index/descendants/_descendant (37.9ms)
Rendered family_index/surname_groups/_pedigree (3162.9ms)
Rendered shared/_headers (4.6ms)
Rendered shared/_new_messages (0.6ms)
Rendered shared/_home_logo (1.1ms)
Rendered shared/_login_box (4.0ms)
Rendered shared/_navigation (13.6ms)
Rendered shared/_flash_messages (0.8ms)
Rendered shared/_footer (1.0ms)
Rendered shared/_analytics (0.8ms)
Completed in 4552ms (View: 3352, DB: 147) | 200 OK [http://localhost/family_index/surname_groups/31]
Ruby 1.9
Rendered family_index/descendants/_fi_hover (0.3ms)
Rendered family_index/descendants/_descendant (1.9ms)
Rendered search/_search_div (0.1ms)
Rendered family_index/descendants/_fi_hover (0.4ms)
Rendered family_index/descendants/_descendant (2.0ms)
Rendered search/_search_div (0.1ms)
Rendered family_index/descendants/_fi_hover (0.3ms)
Rendered family_index/descendants/_descendant (1.9ms)
Rendered family_index/descendants/_fi_hover (0.3ms)
Rendered family_index/descendants/_descendant (15.1ms)
Rendered family_index/surname_groups/_pedigree (762.8ms)
Rendered shared/_headers (2.6ms)
Rendered shared/_new_messages (0.7ms)
Rendered shared/_home_logo (0.9ms)
Rendered shared/_login_box (3.6ms)
Rendered shared/_navigation (7.3ms)
Rendered shared/_flash_messages (0.7ms)
Rendered shared/_footer (0.8ms)
Rendered shared/_analytics (0.6ms)
Completed in 5736ms (View: 942, DB: 128) | 200 OK [http://localhost/family_index/surname_groups/31]
It appears that Ruby 1.9 is rendering the views and processing the database faster, but is still completing the request slower.
Ruby 1.8:
Completed in 4552ms (View: 3352, DB: 147) | 200 OK [http://localhost/family_index/surname_groups/31]
Ruby 1.9:
Completed in 5736ms (View: 942, DB: 128) | 200 OK [http://localhost/family_index/surname_groups/31]
Update 10-26-2010
I've found the bottleneck in my code. It comes from a line that loads up a ton of ActiveRecord items using the lazy-eager loaded associations. The DB time is small, but I'm guessing that all of the object allocation is taking a toll. Here is my association:
has_many :deep_branches,
:class_name => "FamilyIndex::Branch",
:include => {
:descendant => [:state, :county, {:wives => {:marriage => [:state,:county,:reference] }}, :reference, {
:children => [:state, :county, {:wives => {:marriage => [:state,:county,:reference] }}, :reference, {
:children => [:state, :county, {:wives => {:marriage => [:state,:county,:reference] }}, :reference, {
:children => [:state, :county, {:wives => {:marriage => [:state,:county,:reference] }}, :reference] # add marriages to this data
}]
}]
}]
}
Without doing the eager loading, the complete action takes about 40 seconds to complete, so using the :include gives about a 10x performance increase. Still looking for a way to speed this up. Perhaps caching is the only way to go from here.