Skip to content

Instantly share code, notes, and snippets.

@alexch
Forked from nex3/bench.rb
Created May 20, 2009 23:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alexch/115155 to your computer and use it in GitHub Desktop.
Save alexch/115155 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# Alex's changes:
# * erector and erector_mixin
# * each template now includes a loop and a variable (this affects HAML quite a lot)
# * automated comparison and benchmarking
# * make sure variable is truly being interpolated
# # of iterations = 10000
# user system total real
# tagz 13.740000 0.070000 13.810000 ( 14.064954)
# erector 6.500000 0.050000 6.550000 ( 6.744592)
# erector_mixin 6.390000 0.040000 6.430000 ( 6.508313)
# nokogiri 5.950000 0.040000 5.990000 ( 6.137619)
# builder 17.810000 0.090000 17.900000 ( 18.166922)
# haml 5.080000 0.030000 5.110000 ( 5.175749)
# erubis 0.400000 0.010000 0.410000 ( 0.411160)
# markaby 27.620000 0.130000 27.750000 ( 28.234580)
require 'benchmark'
require 'rubygems'
require 'markaby'
require 'tagz'
require 'builder'
require 'erector'
require 'nokogiri'
require 'haml'
require 'erubis'
include Erector::Mixin
max = (ARGV.shift || 10000).to_i
def do_nothing url
url
end
class String
def smush!
gsub!(/^ */, '').gsub!(/\n/, '')
end
end
@obj = Object.new
eruby = <<-EOF
<html>
<head>
<title>happy title</title>
</head>
<body>
<h1>happy heading</h1>
<% 10.times do %>
<a href="<%= url %>">a link</a>
<% end %>
</body>
</html>
EOF
eruby.smush!
Erubis::Eruby.new(eruby).def_method(@obj, "erubis(url)")
def do_erubis url
@obj.erubis(url)
end
haml = <<-EOF
%html
%head
%title happy title
%body
%h1 happy heading
- 10.times do
%a{:href => url} a link
EOF
Haml::Engine.new(haml, :ugly => true).def_method(@obj, :haml, :url)
def do_haml url
@obj.haml(:url => url)
end
def do_tagz url
Tagz {
html_ {
head_ {
title_ "happy title"
}
body_ {
h1_ "happy heading"
10.times do
a_ "a link", :href => url
end
}
}
}
end
class Happy < Erector::Widget
def content
html {
head {
title "happy title"
}
body {
h1 "happy heading"
10.times do
a "a link", :href => @url
end
}
}
end
end
def do_erector url
Happy.new(:url => url).to_s
end
def do_erector_mixin url
erector(:locals => {:url => url}) {
html {
head {
title "happy title"
}
body {
h1 "happy heading"
10.times do
a "a link", :href => url
end
}
}
}
end
def do_builder url
Builder::XmlMarkup.new.html { |xm|
xm.head {
xm.title "happy title"
}
xm.body {
xm.h1 "happy heading"
10.times do
xm.a "a link", :href => url
end
}
}
end
def do_markaby url
mab = Markaby::Builder.new :output_meta_tag => false
mab.html {
head {
title "happy title"
}
body {
h1 "happy heading"
10.times do
a "a link", :href => url
end
}
}.to_s
end
def do_nokogiri url
html = Nokogiri do
html do
head do
title "happy title"
end
body do
h1 "happy heading"
10.times do
a "a link", :href => url
end
end
end
end
html.to_s
end
engines = %w{tagz erector erector_mixin nokogiri builder haml erubis markaby}
previous = nil
previous_engine = nil
engines.each do |engine|
html = send "do_#{engine}", "http://example.com"
# strip whitespace from engines I don't know how to disable it on
html.smush! if engine == "nokogiri" || engine == "haml"
html.gsub!(/'/, '"') if engine == "haml"
if previous && previous != html
puts previous_engine
p previous
puts engine
p html
raise "#{previous_engine} vs. #{engine}"
end
previous = html
previous_engine = engine
end
puts "# of iterations = #{max}"
Benchmark::bm(20) do |x|
engines.each do |engine|
x.report(engine) do
max.times do |i|
url = "http://example.com/#{i}"
html = send "do_#{engine}", url
raise "bad html from #{engine}: #{html}" unless (html.match(url))
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment