[Ruby] String concatenation performance in Rails partials
Eric Hodel
drbrain at segment7.net
Wed Nov 29 01:58:06 PST 2006
On Nov 29, 2006, at 0113 , Tom Lianza wrote:
> Evan and a few others saw me working on this problem tonight, and I
> just
> stumbled upon a development that was fairly surprising to me.
>
> Basically, I have a chunk of HTML I want to render, say, 50 times
> on a page
> (this is a 'search results' page). Each of the objects looks very
> similar,
> so I use a partial, and call it 50 times. Rails has a convenient
> way of
> doing this:
>
> <%=render(:partial=>'list_item', :collection=>bookmark_list)%>
> (bookmark_list is an array of 50 things)--------------^
>
> The problem is that this seemed to be taking a long time to
> render. The DB
> query was quick, but the rendering took 2.5 seconds per request
> (benchmark
> of 6 consecutive requests):
> user system total real
> 2.270000 0.040000 2.310000 ( 2.483692)
> 2.230000 0.030000 2.260000 ( 2.488522)
> 2.230000 0.020000 2.250000 ( 2.477388)
> 2.250000 0.040000 2.290000 ( 2.622520)
> 2.250000 0.040000 2.290000 ( 2.768218)
> 2.270000 0.030000 2.300000 ( 2.727301)
>
> Here's the thing that's really weird - I ripped out the code I was
> looping
> on (the ruby and html in the list_item partial) and replaced it
> with totally
> static code - no ruby at all. The performance was virtually
> *identical.*
>
> So, on a hunch, I took that partial (about 40 lines html) and
> removed all of
> the whitespace, so it was all on one line. The performance changed
> fairly
> dramatically:
>
> user system total real
> 1.500000 0.020000 1.520000 ( 1.808402)
> 1.470000 0.030000 1.500000 ( 1.698254)
> 1.470000 0.020000 1.490000 ( 1.905468)
> 1.460000 0.020000 1.480000 ( 1.622462)
> 1.500000 0.030000 1.530000 ( 1.923870)
> 1.490000 0.030000 1.520000 ( 2.136822)
>
> Rendering time was cut by about 1/3.
>
> If I cut down the html so I'm rendering a tiny amount (like one
> short line)
> the whole thing screams. So... this really smells to me like some
> kind of
> string concatenation problem/slowdown. Is anyone familliar with
> these kinds
> of issues in Ruby? Or, might there be an issue in the Rails code?
> I had
> never heard any recommendations that stripping whitespace out of
> templates
> improves performance in any way, so I feel like this kind of
> behavior is not
> by design.
str = ""
str << a
str << b
str << c
is slower than
str = []
str << a
str << b
str << c
str = str.join
Because (among other reasons) String#<< works the garbage collector
more than Array#join. ERb/eruby uses the former when it should use
the latter.
--
Eric Hodel - drbrain at segment7.net - http://blog.segment7.net
I LIT YOUR GEM ON FIRE!
More information about the Ruby
mailing list