Helpers vs. Partials - A Performance Question

Have you ever looked in your development log and seen something like the following?

 Processing FoosController#show (for ...) [GET] Session ID: BAh7CDoOcmV0dXJuX3R... SQL (0.000869) SHOW TABLES SQL (0.000931) SHOW TABLES Image Load (0.000465) SELECT images.* FROM ... [...] Rendered entries/_detail (0.00221) Rendered entries/_detail (0.00103) Rendered entries/_detail (0.00118) Rendered entries/_detail (0.00092) Rendered entries/_detail (0.00107) Rendered entries/_detail (0.00069) Rendered entries/_detail (0.00215) Rendered entries/_detail (0.00113) Rendered entries/_detail (0.00113) Rendered entries/_detail (0.00098) Rendered entries/_detail (0.00098) Rendered entries/_detail (0.00087) Rendered entries/_detail (0.00079) Rendered entries/_detail (0.00086) Rendered entries/_detail (0.00079) Rendered entries/_detail (0.00087) Rendered entries/_detail (0.00076) Rendered entries/_detail (0.00081) Rendered shared/_nav (0.00207) Rendered shared/_analytics (0.00011) Rendered shared/_footer (0.00188) Completed in 1.63867 (0 reqs/sec) | Rendering: 0.40653 (24%) ... 

These sorts of entries in the log have always felt like a code smell to me - even when some sort of markup reuse is obviously necessary (so you can't just do it inline), I can't help but think that there's some significant cost to rendering the same file over and over again. So after a long time of thinking about it, I finally got around to doing some benchmarks comparing generating markup in a helper method, rendering a partial repeatedly for a collection, and rendering a partial with the :collection key. For each method, I use apache benchmark to hit a page 1000 times (with 2 simultaneous requests); each request generated 1000 divs like this:

<div> <span>index</span> <a href="#">link</a> </div> 

Here's what I found:

Method Time per Request    Requests/Second   
Helper 186.998 ms 10.70
Partial 438.244 ms 4.56
Partial for collection    266.068 ms 7.52

So it looks like there is a cost to rendering a partial repeatedly, but that cost can be reduced by using the :collection key, and reduced even further by generating the markup in a helper method. Of course, the helper method can be a smell of its own, but if performance is an issue it may be worth a look.

Note: This is an unscientific test, so feel free to respond with your own benchmarks.

Ben Scofield

,
Posted in Article Category: #Code
on