Skip to content

Instantly share code, notes, and snippets.

@dcolthorp
Created October 16, 2008 01:26
Show Gist options
  • Select an option

  • Save dcolthorp/17044 to your computer and use it in GitHub Desktop.

Select an option

Save dcolthorp/17044 to your computer and use it in GitHub Desktop.
require 'merb-core'
require 'merb-haml'
END {
require 'rbench'
expando = Expando.new
raise "haml's not fair" unless expando.efficient_haml == expando.naive_haml
raise "erb's not fair" unless expando.efficient_erb == expando.naive_erb
# Results on my machine:
# | naive | expand | naive/expand |
# ---------------------------------------------------------
# haml x10000 | 2.730 | 0.633 | 4.31x |
# erb x10000 | 1.600 | 0.402 | 3.98x |
RBench.run(10_000) do
column :times
column :naive, :title => "naive"
column :expand, :title => "expand"
column :diff, :title => "naive/expand", :compare => [:naive,:expand]
report "haml" do
expand do
expando.efficient_haml
end
naive do
expando.naive_haml
end
end
report "erb" do
expand do
expando.efficient_erb
end
naive do
expando.naive_erb
end
end
end
}
module Templatizer
module Compiled
end
FakeIo = Struct.new :read, :path
def expand_template(type, string, values={})
context = caller[0]
mname = :"__expanded__#{context.gsub(%r{\W}, '_')}"
extend ::Templatizer::Compiled
unless respond_to? mname
string = string.dedent
io = FakeIo.new string, context.scan(/.*?:\d+/).first
Merb::Template.engine_for(".#{type}").compile_template(io, mname, values.keys, ::Templatizer::Compiled)
end
send(mname, values)
end
end
class Object
include Templatizer
end
class String
def dedent
min_size = Float::MAX
self.scan(/^( *)\S/).each do |indentation, ignored|
min_size = [min_size, indentation.length].min
end
self.gsub(/^ {0,#{min_size}}/, '')
end
end
class Expando
def initialize
@instance = "YO"
end
def efficient_haml
expand_template(:haml, <<-HAML, :a => 1)
= @instance
= a
HAML
end
def naive_haml
haml = Haml::Engine.new <<-EOS.dedent
= @instance
= a
EOS
haml.render self, :a => 1
end
def efficient_erb
expand_template(:erb, <<-ERB, :a => 1)
<%= @instance %>
<%= a %>
ERB
end
def naive_erb
eruby = ::Erubis::BlockAwareEruby.new(<<-ERB.dedent)
<%= @instance %>
<%= @a %>
ERB
eruby.evaluate :a => 1, :instance => @instance
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment