Yehuda Katz is a member of the Ruby on Rails core team, and lead developer of the Merb project. He is a member of the jQuery Core Team, and a core contributor to DataMapper. He contributes to many open source projects, like Rubinius and Johnson, and works on some he created himself, like Thor.
@olivierlacan sorry :( my office sucks for podcasts; WiFi and rooms. Was the content bad or just the audio? I wish to improve!
Status Memorandum
December 27th, 2008
Today was another great day working on improving Rails. What happened today:
- I made my first commits to Rails. The commits remove the use of method_missing in respond_to. Effectively, when you did respond_to {|format| format.html }, the format object was a Responder object that collected up the mime types you specified and then followed your instructions. However, the html method was not defined on Responder. Instead, Responder relied on method_missing to determine, on the fly, whether html was a valid mime type.
- The fix was to generate methods for all known mime types in advance. In addition, when method_missing is triggered and a valid mime type is detected, Rails now generates a method on the fly (so at maximum single method_missing will be called for a particular method). The main win here is that since the method is generated, it’s not longer necessary to check whether the mime exists every time. If you get to the format.html method, that’s evidence that the mime exists, since it cannot otherwise be generated.
- The upside: 8% full-stack speed-boost on both MRI and JRuby for a simple case (bringing the full-stack overhead when using respond_to down from 2.5ms to 2.3ms). It may not seem like a lot, but 0.2ms here, 0.2ms there, and pretty soon you’re talking big… amounts of time?
- I did a lot of benchmarking on BlockAwareEnhancer. It turns out that for JRuby, the <%= form_for %>…<% end =%> syntax can bring down a page heavy with block helpers (1,000 block helpers to be precise) down from 30ms to 8ms. In MRI, the same technique brings the total time from 80ms to 65ms. (yes, that is a shockingly good result for JRuby… seems like there are very common, expensive operations that JRuby kicks butt on).
- Carl is working hard on making the router super-easy to hook into with any front-end DSL. This will help us easily maintain backward compatibility with current Merb syntax, while giving us the ability to give Rails all the new features of the Merb router with a familiar syntax.
- Michael (antares) continues his work on analyzing parts of Extlib that should go in ActiveSupport, comparing the compatibility of the modules, and bringing in new features (LazySet and DeferredModule come to mind). The idea is to make it easier to opt in to small parts of ActiveSupport with the ability to clearly know what will get pulled in as a result.


Ciaran Lee, Posted December 27, 2008, 9:33 am
Congratulations, it’s great to see the work proceeding at such pace!
Greg, Posted December 27, 2008, 2:02 pm
Out of curiosity, what’s the advantage of respond_to blocks over Merb-style case content_type? I would assume that the case statement would generally perform better due to fewer blocks being created, and I find it a bit more readable as well.
Yehuda Katz, Posted December 27, 2008, 2:15 pm
@greg Rails3 will support the case form for performance. Part of the win of respond_to is that it allows you to declare, at once, the list of things your action responds with, and how it should respond.
Consider the Merb alternative:
def action only_provides :xml, :json case content_type when :xml #stuff when :json #stuff end endvs.
def action respond_to do |format| format.xml { #stuff } format.json { #stuff } end endOne of the things I will be working heavily on is finding a way to make the respond_to way more performant. I think I can squeeze out enough performance out of it to make it a moot point for most cases (see my initial commits referenced in the post for some initial work). However, I will also be working on making sure that the raw-ruby performant version works as expected.
Cool?
teamon, Posted December 27, 2008, 5:23 pm
backward compatibility is gonna kill you…
btw, what about
def action
only_provides :xml, :json
case content_type
when :xml, :html, :my_own_content_type
#stuff
when :json
#stuff
end
end
?
wycats, Posted December 27, 2008, 5:33 pm
teamon: in that case, content_type will never be :my_own_content_type in Merb (because content_type is the first provided content-type that is also Accepted).
teamon, Posted December 27, 2008, 5:52 pm
But what about having same #stuff for several content_types ?
wycats, Posted December 27, 2008, 6:00 pm
teamon: Someone recently proposed format.any(:js, :html) { #stuff }. I think that’s a worthy proposal and I suspect it’ll make it in.
Keep in mind that the old case syntax will still work and I’ll be working on a few inconsistencies in the way it works to make sure everything is works great.
teamon, Posted December 27, 2008, 6:05 pm
Well, that is a option.
Last thing (i go to bed ;p) – it looks like rails3 will have saveral public APIs for some case and i`m not sure if thats a good idea.
While it looks like rails-patching i still hope rails3 will be awesome…
wycats, Posted December 27, 2008, 7:23 pm
@teamon it doesn’t feel like Rails patching to me. It feels like finding a way to incorporate the Rails DSL into the way Merb does things (while keeping it performant). The specific contours of it will depend on how performant we can make respond_to (I have some really good ideas for how to make the overhead almost nil).
Maik Kempe, Posted December 27, 2008, 8:50 pm
Thanks for your great work and sharing. 2009 will be so awesome!
Charles Oliver Nutter, Posted December 28, 2008, 12:52 am
Great looking JRuby numbers :) Here’s hoping this is the year we’re finally able to make JRuby the fastest way to run Rails.
David Burry, Posted December 31, 2008, 8:06 pm
Regarding the 0.2ms improvement here and there, the biggest win isn’t the performance gain per se in cases like this, but the restructuring itself.
When code is well structured and optimized it makes happy programmers because:
* it’s easier to understand and work on, and that’s what drew most of us to Ruby to begin with, so obviously that’s important to all of us.
* As a welcome side effect such optimizations also mean less bugs and gotchas maintaining going forward,
* and a bit of performance gain too whee.
* And of course there’s the sense of beauty and pride when code is well organized and optimized instead of slightly messy. Like picking up the dirty socks off the floor before friends come over to visit. ;o)
So again, thanks for all your great work on this.