Skip to content

Instantly share code, notes, and snippets.

@luislavena
Created October 16, 2010 21:49
Show Gist options
  • Save luislavena/630310 to your computer and use it in GitHub Desktop.
Save luislavena/630310 to your computer and use it in GitHub Desktop.
Measure Ruby template engines
require 'benchmark'
require 'erb'
require 'erubis'
#gem 'haml', '3.0.21'
gem 'haml', '3.1.0.alpha.14'
require 'haml'
# 0.6.0 beta automatically escapes html
gem 'slim', '~> 0.6.0.beta.3'
require 'slim'
erb = <<-ERB
<!doctype html>
<html>
<head>
<title>Test</title>
</head>
<body>
<h1>simple markup</h1>
<div id="content">
<% unless items.empty? %>
<% items.each do |item| %>
<li><%= item %></li>
<% end %>
<% else %>
<p>No items</p>
<% end %>
</div>
<%= tags %>
</body>
</html>
ERB
haml= <<-HAML
!!! html
%html
%head
%title Test
%body
%h1 simple markup
#content
- unless items.empty?
- items.each do |item|
%li= item
- else
%p No items
= tags
HAML
slim = <<-SLIM
! doctype html
html
head
title Test
body
h1 simple markup
div#content
- unless items.empty?
ol
- items.each do |item|
li
= item
- else
p No items
= tags
SLIM
class Context
def items
@items ||= [1, 2, 3, 4, 5]
end
def tags
@tags ||= "<p>Something<span>here</span></p>"
end
end
cxt = Context.new
# Ruby's ERB doesn't like Hash parameters like Erubis
erb_cxt = cxt.instance_eval { binding }
n = 10_000
Benchmark.bmbm do |bench|
bench.report('emtpy loop') { n.times { } }
# compute template every time
bench.report('erb') { n.times { ERB.new(erb).result(erb_cxt) } }
bench.report("erubis #{Erubis::VERSION}") { n.times { Erubis::Eruby.new(erb).result(:items => cxt.items, :tags => cxt.tags) } }
bench.report("fast erubis #{Erubis::VERSION}") { n.times { Erubis::FastEruby.new(erb).result(:items => cxt.items, :tags => cxt.tags) } }
bench.report("haml #{Haml::VERSION}") { n.times { Haml::Engine.new(haml, :format => :html5).render(cxt) } }
bench.report("haml (ugly) #{Haml::VERSION}") { n.times { Haml::Engine.new(haml, :format => :html5, :ugly => true).render(cxt) } }
bench.report('slim') { n.times { Slim::Engine.new(slim).render(cxt) } }
# cache compiled template
bench.report('erb (cached)') { t = Erubis::Eruby.new(erb); n.times { t.result(erb_cxt) } }
bench.report("erubis #{Erubis::VERSION} (cached)") { t = Erubis::Eruby.new(erb); n.times { t.result(:items => cxt.items, :tags => cxt.tags) } }
bench.report("fast erubis #{Erubis::VERSION} (cached)") { t = Erubis::FastEruby.new(erb); n.times { t.result(:items => cxt.items, :tags => cxt.tags) } }
bench.report("haml #{Haml::VERSION} (cached)") { t = Haml::Engine.new(haml, :format => :html5); n.times { t.render(cxt) } }
bench.report("haml (ugly) #{Haml::VERSION} (cached)") { t = Haml::Engine.new(haml, :format => :html5, :ugly => true); n.times { t.render(cxt) } }
bench.report('slim (cached)') { t = Slim::Engine.new(slim); n.times { t.render(cxt) } }
end
ruby 1.8.7 (2010-08-16 patchlevel 302) [i386-mingw32]
Rehearsal ---------------------------------------------------------------------------------------
emtpy loop 0.000000 0.000000 0.000000 ( 0.001000)
erb 4.337000 0.000000 4.337000 ( 4.352249)
erubis 2.6.6 2.948000 0.000000 2.948000 ( 2.945168)
fast erubis 2.6.6 2.949000 0.000000 2.949000 ( 2.943169)
haml 3.1.0.alpha.14 (Bleeding Edge) 24.960000 0.000000 24.960000 ( 24.987429)
haml (ugly) 3.1.0.alpha.14 (Bleeding Edge) 23.899000 0.000000 23.899000 ( 23.921368)
slim 5.538000 0.000000 5.538000 ( 5.570319)
erb (cached) 0.718000 0.000000 0.718000 ( 0.710040)
erubis 2.6.6 (cached) 0.983000 0.000000 0.983000 ( 0.980056)
fast erubis 2.6.6 (cached) 0.889000 0.000000 0.889000 ( 0.902052)
haml 3.1.0.alpha.14 (Bleeding Edge) (cached) 1.654000 0.000000 1.654000 ( 1.653095)
haml (ugly) 3.1.0.alpha.14 (Bleeding Edge) (cached) 1.201000 0.000000 1.201000 ( 1.187068)
slim (cached) 0.686000 0.000000 0.686000 ( 0.697039)
----------------------------------------------------------------------------- total: 70.762000sec
user system total real
emtpy loop 0.000000 0.000000 0.000000 ( 0.001000)
erb 4.368000 0.000000 4.368000 ( 4.371250)
erubis 2.6.6 2.886000 0.000000 2.886000 ( 2.923168)
fast erubis 2.6.6 2.933000 0.000000 2.933000 ( 2.934168)
haml 3.1.0.alpha.14 (Bleeding Edge) 24.789000 0.000000 24.789000 ( 24.791418)
haml (ugly) 3.1.0.alpha.14 (Bleeding Edge) 23.930000 0.000000 23.930000 ( 23.942370)
slim 5.522000 0.000000 5.522000 ( 5.551318)
erb (cached) 0.702000 0.000000 0.702000 ( 0.708041)
erubis 2.6.6 (cached) 0.983000 0.000000 0.983000 ( 0.979056)
fast erubis 2.6.6 (cached) 0.890000 0.000000 0.890000 ( 0.894051)
haml 3.1.0.alpha.14 (Bleeding Edge) (cached) 1.669000 0.000000 1.669000 ( 1.673095)
haml (ugly) 3.1.0.alpha.14 (Bleeding Edge) (cached) 1.202000 0.000000 1.202000 ( 1.200068)
slim (cached) 0.686000 0.000000 0.686000 ( 0.701040)
ruby 1.9.2p0 (2010-08-18) [i386-mingw32]
Rehearsal ---------------------------------------------------------------------------------------
emtpy loop 0.000000 0.000000 0.000000 ( 0.001000)
erb 3.198000 0.000000 3.198000 ( 3.202183)
erubis 2.6.6 2.761000 0.000000 2.761000 ( 2.764158)
fast erubis 2.6.6 2.668000 0.000000 2.668000 ( 2.679153)
haml 3.1.0.alpha.14 (Bleeding Edge) 19.671000 0.000000 19.671000 ( 19.721128)
haml (ugly) 3.1.0.alpha.14 (Bleeding Edge) 18.689000 0.000000 18.689000 ( 18.714070)
slim 4.524000 0.000000 4.524000 ( 4.540260)
erb (cached) 0.936000 0.000000 0.936000 ( 0.932053)
erubis 2.6.6 (cached) 1.280000 0.000000 1.280000 ( 1.280074)
fast erubis 2.6.6 (cached) 1.170000 0.000000 1.170000 ( 1.175067)
haml 3.1.0.alpha.14 (Bleeding Edge) (cached) 1.887000 0.000000 1.887000 ( 1.887108)
haml (ugly) 3.1.0.alpha.14 (Bleeding Edge) (cached) 1.451000 0.000000 1.451000 ( 1.441082)
slim (cached) 1.170000 0.000000 1.170000 ( 1.178068)
----------------------------------------------------------------------------- total: 59.405000sec
user system total real
emtpy loop 0.000000 0.000000 0.000000 ( 0.001000)
erb 3.229000 0.000000 3.229000 ( 3.216184)
erubis 2.6.6 2.730000 0.000000 2.730000 ( 2.728156)
fast erubis 2.6.6 2.652000 0.000000 2.652000 ( 2.661153)
haml 3.1.0.alpha.14 (Bleeding Edge) 19.844000 0.000000 19.844000 ( 19.849135)
haml (ugly) 3.1.0.alpha.14 (Bleeding Edge) 18.782000 0.000000 18.782000 ( 18.839078)
slim 4.462000 0.000000 4.462000 ( 4.488256)
erb (cached) 0.905000 0.000000 0.905000 ( 0.918052)
erubis 2.6.6 (cached) 1.295000 0.000000 1.295000 ( 1.300075)
fast erubis 2.6.6 (cached) 1.138000 0.000000 1.138000 ( 1.152066)
haml 3.1.0.alpha.14 (Bleeding Edge) (cached) 1.904000 0.000000 1.904000 ( 1.912109)
haml (ugly) 3.1.0.alpha.14 (Bleeding Edge) (cached) 1.450000 0.000000 1.450000 ( 1.450083)
slim (cached) 1.170000 0.000000 1.170000 ( 1.164066)
@stonean
Copy link

stonean commented Oct 17, 2010

Slim escapes html by default, so to be a functional comparison you'll need to use == in Slim to bypass the escape call.

@luislavena
Copy link
Author

Indeed, but I forgot to mention that Slim cached is not only faster than erubis or close to fast erubis but also safer, 2 for the same price :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment