tagz vs markaby/builder/haml/erubis
Published 2009-02-16 @ 00:19
Tagged rails, thoughts
I’ve been meaning to write and run this benchmark for a while to see how things fare in the view world these days. Initially I did markaby vs tagz (my favorite at a svelte 244 lines). I then added builder out of curiosity’s sake. Thanks to atmos I was able to get code and numbers for erubis and haml.
Builder is slightly faster than tagz, but not enough for me to want to switch to it. Tagz and markaby read so much better than builder, but markaby is so much slower (4.73 times slower than builder) that I can’t justify its use.
Now if only I could get tagz working correctly with sinatra. :(
# iterations = 10000
#
# user system total real multiplier
#
# builder 1.910000 0.000000 1.910000 ( 1.918751) (1.00)
# tagz 2.310000 0.020000 2.330000 ( 2.357710) (1.23)
# haml 5.370000 0.020000 5.390000 ( 5.418876) (2.82)
# erubis 5.390000 0.020000 5.410000 ( 5.446929) (2.84)
# markaby 8.980000 0.030000 9.010000 ( 9.078748) (4.73)
Code behind the cut…
Code:
#!/usr/bin/env ruby
require 'benchmark'
require 'rubygems'
require 'markaby'
require 'tagz'
max = (ARGV.shift || 1_000_000).to_i
def do_nothing
# do nothing
end
require 'haml'
require 'erubis'
def do_erubis
str = <<-EOF
<html>
<head>
<title>happy title</title>
</head>
<body>
<h1>happy heading</h1>
<a href='<%= 'url' %>'>a link</a>
</body>
</html>
EOF
eruby = Erubis::Eruby.new(str)
end
def do_haml
str = <<-EOF
%html
%head
%title_ "happy title"
%body
%h1 "happy heading"
%a "a link", :href => "url"
EOF
Haml::Engine.new(str)
end
def do_tagz
Tagz {
html_ {
head_ {
title_ "happy title"
}
body_ {
h1_ "happy heading"
a_ "a link", :href => "url"
}
}
}
end
def do_builder
Builder::XmlMarkup.new.html {
xm.head {
xm.title "happy title"
}
xm.body {
xm.h1 "happy heading"
xm.a "a link", :href => "url"
}
}
end
def do_markaby
mab = Markaby::Builder.new :output_meta_tag => false
mab.html {
head {
title "happy title"
}
body {
h1 "happy heading"
a "a link", :href => "url"
}
}.to_s
end
x = do_tagz
y = do_markaby
z = do_builder
raise "bad!\n\n#{x}\n\n#{y}" unless x == y
raise "bad!\n\n#{x}\n\n#{z}" unless x == z
puts "# of iterations = #{max}"
Benchmark::bm(20) do |x|
x.report("null_time") do
for i in 0..max do
do_nothing
end
end
x.report("tagz") do
for i in 0..max do
do_tagz
end
end
x.report("markaby") do
for i in 0..max do
do_markaby
end
end
x.report("builder") do
for i in 0..max do
do_builder
end
end
end