Slim VS. Haml: Performance Perspective

 Background

Slim and Haml are two popular template language for Ruby on Rails, and there are many debates on which one is better all over the internet.

Luckily there are some benchmark tools on GitHub which may help to make a final decision.

I just pick up one from the official Slim GitHub repository: https://github.com/slim-template/slim

How-to Run Benchmark Test

Step 1: clone the code

$ git clone https://github.com/slim-template/slim

Step 2: install haml and slim for your rubies

$ gem install haml slim -N

On this post is written the slim version is 2.0.2 and haml version is 4.0.5.
Step 3: run the benchmark and review the generated report

$ cd benchmarks
$ ruby run-benchmarks.rb
1000 Iterations
Rehearsal ---------------------------------------------------
(1) erb           0.040000   0.000000   0.040000 (  0.035554)
(1) erubis        0.030000   0.000000   0.030000 (  0.034831)
(1) fast erubis   0.030000   0.000000   0.030000 (  0.028304)
(1) temple erb    0.060000   0.000000   0.060000 (  0.061399)
(1) slim pretty   0.090000   0.000000   0.090000 (  0.091697)
(1) slim ugly     0.050000   0.000000   0.050000 (  0.048000)
(1) haml pretty   0.250000   0.000000   0.250000 (  0.247935)
(1) haml ugly     0.220000   0.000000   0.220000 (  0.220167)
(2) erb           0.090000   0.000000   0.090000 (  0.093170)
(2) erubis        0.070000   0.000000   0.070000 (  0.065629)
(2) temple erb    0.080000   0.000000   0.080000 (  0.083807)
(2) slim pretty   0.140000   0.000000   0.140000 (  0.134829)
(2) slim ugly     0.090000   0.000000   0.090000 (  0.087713)
(2) haml pretty   0.280000   0.000000   0.280000 (  0.286019)
(2) haml ugly     0.280000   0.000000   0.280000 (  0.281315)
------------------------------------------ total: 1.800000sec

                      user     system      total        real
(1) erb           0.030000   0.000000   0.030000 (  0.031230)
(1) erubis        0.030000   0.000000   0.030000 (  0.027214)
(1) fast erubis   0.020000   0.000000   0.020000 (  0.019729)
(1) temple erb    0.050000   0.000000   0.050000 (  0.050958)
(1) slim pretty   0.090000   0.000000   0.090000 (  0.087899)
(1) slim ugly     0.040000   0.000000   0.040000 (  0.039730)
(1) haml pretty   0.230000   0.000000   0.230000 (  0.232516)
(1) haml ugly     0.210000   0.000000   0.210000 (  0.214131)
(2) erb           0.070000   0.000000   0.070000 (  0.079034)
(2) erubis        0.050000   0.000000   0.050000 (  0.052715)
(2) temple erb    0.090000   0.000000   0.090000 (  0.081411)
(2) slim pretty   0.120000   0.000000   0.120000 (  0.121075)
(2) slim ugly     0.070000   0.000000   0.070000 (  0.067838)
(2) haml pretty   0.280000   0.000000   0.280000 (  0.285198)
(2) haml ugly     0.260000   0.000000   0.260000 (  0.258908)

(1) Compiled benchmark. Template is parsed before the benchmark and
    generated ruby code is compiled into a method.
    This is the fastest evaluation strategy because it benchmarks
    pure execution speed of the generated ruby code.

(2) Compiled Tilt benchmark. Template is compiled with Tilt, which gives a more
    accurate result of the performance in production mode in frameworks like
    Sinatra, Ramaze and Camping. (Rails still uses its own template
    compilation.)

(3) Parsing benchmark. Template is parsed every time.
    This is not the recommended way to use the template engine
    and Slim is not optimized for it. Activate this benchmark with 'rake bench slow=1'.

Temple ERB is the ERB implementation using the Temple framework. It shows the
overhead added by the Temple framework compared to ERB.

My Customized Benchmark Test

Default iteration is 1000, which makes the difference too small, so I update it to 100,000 in run-benchmarks.rb
Then I run 9 rounds of test under this configuration matrix:

Ruby 1.9.3 Ruby 2.0.0 Ruby 2.1.1
Rails 3.2.17
Rails 4.0.4
Rails 4.1.0

Compiled benchmark mode

Row Data

Ruby Version Rails Version erb erubis fast erubis temple erb slim pretty slim ugly haml pretty haml ugly slim ugly vs. erb
1.9.3 3.2.17 4.33 3.65 3.65 6.62 9.13 5.16 26.64 24.99 19.17%
4.0.4 4.31 3.63 3.7 6.2 9.07 5.15 26.39 24.85 19.49%
4.1.0 4.11 3.47 3.63 6.09 8.87 5.06 26.02 24.4 23.11%
2.0.0 3.2.17 3.81 3.32 3.17 6.2 9.55 4.78 25.19 22.41 25.46%
4.0.4 3.83 3.35 3.39 6.01 9.4 4.87 25.16 22.29 27.15%
4.1.0 3.75 3.27 3.14 6.15 9.29 4.75 24.94 22.22 26.67%
2.1.1 3.2.17 3.12 2.74 2.81 5.21 8.41 4.31 22.31 20.29 38.14%
4.0.4 3.15 2.75 2.77 5.24 8.51 4.33 21.72 19.9 37.46%
4.1.0 3.11 2.69 2.72 5.08 8.36 4.29 21.75 20.01 37.94%

Ruby/Rails Perspective

slim.vs.haml_01

Figure 1-1: Ruby/Rails Version Perspective – Compiled Benchmark Mode

Template Language Perspective

slim.vs.haml_02

Figure 1-2: Template Language Perspective – Compiled Benchmark Mode

Conclusion

From Figure 1-1 it can be seen that:

  1. Ruby 2.1.1 is a little better than 1.9.3/2.0.0
  2. There is little difference for template languages between 1.9.3 and 2.0.0, except  haml
  3. For haml 2.1.1 > 2.0.0 > 1.9.3
  4. If it is decided to use haml, then you can choose any version of Ruby and Rails.

From Figure 1-2:

  1. Haml is the worst
  2. Slim ugly is worse than erb, from between 19% to 38%.
  3. Comparing slim ugly to erb,  Ruby 1.9.3 has the closest relative percentage , which is about 19% slower, while Ruby 2.1.1 the furthest, which is 38% slower
  4. Slim ugly performs best on 2.1.1 while worst on 1.9,3
  5. There is little difference for slim ugly on any version of Ruby/Rails

Compiled Tilt Benchmark Mode

Row Data

Ruby Version Rails Version erb erubis temple erb slim pretty slim ugly haml pretty haml ugly slim ugly vs. erb
1.9.3 3.2.17 8.61 6.35 9.41 12.49 8.07 28.56 25.61 -6.27%
4.0.4 8.62 6.29 9.67 12.79 8.35 28.36 25.78 -3.13%
4.1.0 8.52 6.15 9.46 12.37 7.98 27.71 25.08 -6.34%
2.0.0 3.2.17 8.57 6.14 9.33 12.97 7.95 29.51 27.55 -7.23%
4.0.4 8.53 6.15 9.23 13.06 7.76 29.81 27.44 -9.03%
4.1.0 8.45 6.06 9.22 12.82 7.86 30.7 27.41 -6.98%
2.1.1 3.2.17 6.54 4.96 7.13 10.51 6.19 22.2 20 -5.35%
4.0.4 6.5 4.91 6.95 10.42 6.15 21.36 19.54 -5.38%
4.1.0 6.48 4.9 6.94 10.36 6.15 21.31 19.39 -5.09%

Ruby/Rails Perspective

slim.vs.haml_03

Figure 1-3: Ruby/Rails Version Perspective – Compiled Tilt Benchmark Mode

Template Language Perspective

slim.vs.haml_04

Figure 1-4: Template Language Perspective – Compiled Tilt Benchmark Mode

Conclusion

From Figure 1-3 it can be concluded that:

  1. Ruby 2.1.1 is a little better thatn 1.9.3/2.0.0,
  2. There is little difference for template languages between 1.9.3 and 2.0.0, except  haml
  3. For haml 2.1.1 > 2.0.0 > 1.9.3
  4. If it is decided to choose haml, then Ruby 2.1. is recommended

From Figure 1-4:

  1. Haml is the worst
  2. Slim ugly is a little better than erb, from between 3% to 9%
  3. Comparing slim ugly to erb,  Ruby 1.9.3 has the best relative percentage , which is about 8% faster
  4. Slim ugly on Ruby 2.1.1 runs the fastest
  5. There is no difference for slim ugly on any version of Rails; meanwhile, Ruby 2.1.1 > 2.0.0 > 1.9.3

Final Conclusion

Slim ugly indeed is much faster than haml, while slightly slower than erb.

Considering coding efficiency and run-time efficiency, maybe slim is the best choice.

Further Benchmark Update

Perhaps I can try different template data, for example, change the structure of view.erb/view.haml/view.slim, to experience more.

10 comments

  1. Joe Hirn

    Nice post and very detailed writeup. Thank you for staying factual and un-opinionated in this comparison. It’s easy to dip into finger pointy mode with such comparisons so I commend you for not doing so.

    I do want to point out that extrapolating your results, haml will add .00025ms (or 0.25ns) of overhead to each page request you serve. Unless you render your page 1000 times per request in which case you add .25ms per request. Not much to worry about unless you’re doing a few 100k requests per second. #amirite?

    But I really do appreciate this blog post. We were having a discussion at work about haml’s poor performance and I was recently introduced to slim. So far, I’m not a fan of the syntax compared to haml. I am however interested to dig more into the implementation of each to discover exactly how they get slim to be an order of magnitude more efficient.

    Cheers.

  2. Phillipp

    As my teacher would say: “what unit is it? puppies?”. tl;dr, so the graphs were useless to me becuase I couldn’t see if 1/s or milliseconds per request or what…

  3. Mathieu

    would be nice if you had added builder to your benchmark.
    it’s pure ruby with Builder::XmlMarkup tool. it always been with rails, since the beginning. it used to have the .rxml extension.

  4. Pingback: 2 – Slim VS. Haml: Performance Perspective | Offer Your
  5. Daniel

    I can do a render inside of my haml and slim code.
    Here is my code:

    doctype html
    html
    head
    title Slim Examples
    javascript:
    alert(‘Slim supports embedded javascript!’)

    body
    h1 Markup examples

    #content
    p This example shows you how a basic Slim file looks.

    div id=”footer”
    == render :partial => ‘footer’

    and this is the error:

    slim pretty(eval):113:in `run_slim_pretty’: undefined method `render’ for # (NoMethodError) from run-benchmarks.rb:49:in `block in init_compiled_benches’.

    Any help?

Leave a comment