HAML: RoR's new templating engine

Seth Thomas Rasmussen wrote:

Checking back in.. I lost steam with HAML. Going back to the few templates I initially converted, I'm not sure I like it as much. I do want to keep an eye on it, though.

Hampton, you commented on DBs being the bottleneck, not rendering, but from what I've heard (including from members of Rails core), rendering has actually been one of the most notorious performance monkeys on our collective back for most of Rails life thus far.

This is just what I've heard, and I'd be interested for more of your take on this.

My bad. I somehow created a new thread that followed this one...

Back to rendering performance. In a templating system, my understanding is that static content is usually pushed to the template and one tries to keep dynamic content to a minimum. Rails has many helpers that are used to transform to static html, for convenience. This can be good but the cost is performance when it is over-used. With rhtml developers do have more control and can balance/tune rendering speed more easily. I don't think the same can be said for HAML.

Long

I’ve noticed consistent problems with rendering times. DB queries (once memcached) doesn’t seem to be an issue. Especially the link helpers and the routes are pretty pathetic when it comes to speed (and even nominally complex routes). I haven’t played around with Edge (or REST) but in the last rails stable, rendering is a bottleneck. Stafan Kaes has a template optimizer (and some pointers to route generation) which has helped me a lot.

Vish

When you guys say “DB is consistantly less than %20”, where do you get that from?

I am certain that for your site that must be true. However, that does also lead me to believe that you aren't doing DB calls that are that intensive. Doing three joins across tables that you can't really cache, because its over several servers and is constantly changing. I generally have DB calls that are about 70% on most of the *major* calls to server.

As far as speed in HAML goes, there are a couple notes about it. We have achieved a 20-30% speedup already in the latest version (0.2)

With silent-scripting, I think that rails-caching probably works now, though I haven't tried it out yet.

And, beyond that, we are currently starting work on building a C compiler for HAML (and its derivatives also in development). Basically, in version 0.2, HAML does some compiling before it gets executed. Very similar to what ERb does. Anyhow, we noticed that we would very likely be able to move this code into a C library and have it spit out HAML buffered-ready code very quickly. Adding that into the codebase (might show up around 0.5) should make us *faster* than ERb.

Though, only time will tell.

Anyhow, I appreciate the feedback on HAML and will take your concerns on speed to heart and work even more on getting speed-ups. However, though I am working to improvements, I don't think that speed should keep anyone from actually using it in production. Yes, it is slower, but its not so slow that your site would come to a crawl in any real sense.

All of our sites still feel zippy.

-hampton.

Just a comment on a C compiler. It seems like optimizing that close
to bare metal will introduce portability issues. In any case, a
different approach would be to introduce an optimizer much as Stephan
Kaes has shown for Erb. The idea is that you do some semantic
evaluation of the code looking for things like loop-invariants,
common sub-expressions, and expensive evaluations that might be
linearized.

I'm still not sure rendering is that big a deal. It's very difficult
to tell where the components divide out, but RailsBench does a pretty
good job of telling you -- is it clear that everyone is suffering
from templating engine overhead? Compiling to C just seems like a big
hammer.

A native version would most likely be a unix-only Gem that can optionally be installed to speed up certain string-manipulations (especially in the pre-compile) stage.

However, also this weekend, I was working on the code-base for the upcoming 0.3 release and added caching (via pre-compiled buffering) to the engine. I was able to achieve a 50% speedup. My benchmarks on v.2 that take 0.5 seconds now take 0.22 seconds (results obviously may vary).

This puts us much closer to where we want to be.

That being said. I agree with you. All of my production apps seem zippy enough. I really don't notice any slow-downs at all. However, that being said, I still think its important to really work on this and keep the code as stable and fast as possible.

-hampton.