Posts tagged performance

Asset bundling in Rails

I stumbled across James Herdman’s piece on asset bundling in rails earlier this week. I’d always presumed you could do this but never got round to investigating as very few of my projects load in very large numbers of JS/CSS assets.

In the end it was quite timely as I’ve been trying to reduce the footprint of an app I’ve recently inherited that is using far too many plugins. With this technique it was very straightforward to remove the asset_packager library. Now, what else can I eliminate…?

Selected (belated, extended) Saturday Links

The past two weeks haven’t really left time to compile my selected links, though there have been many. A few days at SxSWi (on which more, later) followed by travelling with the family and the inevitable work backlog moved blogging way down the priority list. So here’s a mammoth selection to get me caught up. Particularly interesting has been the discussion around the future of newspapers (represented here by Clay Shirky, Steven Johnson and Russell Davies), which seem to have finally pushed beyond “how t ind a good business model for papers” to looking at where the real value for society lies and how we can preserve and extend that in a changing landscape.

Selected Saturday Links

Big themes this week have mostly revolved around twitter, facebook, and openness. Some have focussed on facebook redesigning to embrace a more twitter-like “web of flow” approach, and others on the fact that they’re jumping on various open web bandwagons. It’s been interesting to see some tie in with the government transparency thinking going around, as particularly noted by Chris Messina on FactoryCity. Meanwhile there are quite a few nice new tools emerging, and I really must try heroku one of these days.

Speeding up Rails with erubis

However much we buy into the adage that hardware is cheaper than developers, we all still need to make our code as responsive as possible. We tune the database, we refactor our code, and try to find the optimum balance between developer time, code legibility, and performance. In the process, many of us have found that rails’ rendering, particularly the Erb library is one of its slowest parts. Enter Erubis.

Erubis is an implementation of eRuby that replaces Erb. It‘s written in C and claims to be three times faster than Erb, and 10% faster than its nearest competitor (eruby from mod_ruby which isn’t recommended for use with rails apps). I’ve been trying it out over the past few days, initially with version 2.1 and today with 2.2, and it seemed like time for a report.

Updating an existing rails app is pretty straightforward. I’ve heard that there are some issues to watch out for, but mostly all it takes to convert an existing app is to follow the simple instructions and add:

require 'erubis/helpers/rails_helper'

inside your environment.rb file. Then restart the server, and away you go.

I’ve been testing it out on an app that is fairly early in its lifecycle and hasn’t yet seen much tuning. The app suffers from running too many database queries, but even so it spends more of its time in the rendering than in the database. Running locally off one mongrel I found that, I tested using ‘ab’ from a parallels virtual machine, and found that over 250 requests my standard setup got 7.55 requests/second. Switching to Erubis made little difference to that, which came as quite a surprise.

I then tried applying the patch to rails that the documentation offers as an optional extra. That’s when I saw the real performance leap. Just that change pushed the app up to 13.02 requests/second. I tried it again, and saw 16.29 requests/second. Not quite three times the speed, but doubles not something to be sniffed at. There’s just the small matter of patching rails, which isn’t my first choice as I like to keep this app in step with edge.

But of course this is ruby, so there are alternatives to patching. We can add the new methods in environment.rb before we require the erubis helper and it’ll do the same job.

module ActionView
  class Base
    def convert_template_into_ruby_code(template)
      ERB.new(template, nil, @@erb_trim_mode).src
    end
 
    # Create source code for given template
    def create_template_source(extension, template, render_symbol, locals)
      if template_requires_setup?(extension)
        body = case extension.to_sym
          when :rxml
            "controller.response.content_type ||= 'application/xml'\n" +
            "xml = Builder::XmlMarkup.new(:indent => 2)\n" +
            template
          when :rjs
            "controller.response.content_type ||= 'text/javascript'\n" +
            "update_page do |page|\n#{template}\nend"
        end
      else
        body = convert_template_into_ruby_code(template)
      end
 
      @@template_args[render_symbol] ||= {}
      locals_keys = @@template_args[render_symbol].keys | locals
      @@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h }
 
      locals_code = ""
      locals_keys.each do |key|
        locals_code < < "#{key} = local_assigns[:#{key}]\n"
      end
 
      "def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend"
    end
  end
end

So far, I’m impressed.

Update (17th Feb): I had misread the information and not understood that it is written entirely in ruby. And apparently 2.2 doesn’t have the same issues in rails that 2.1 had.