Project

General

Profile

Actions

Backport #4115

closed

Faster ERB patch

Added by bahuvrihi (Simon Chiang) over 13 years ago. Updated over 4 years ago.

Status:
Closed
Assignee:
-
[ruby-core:33549]

Description

=begin
ERB can be made faster by pushing all string fragments onto an array and then performing one join to make the result, rather than concatenating each string fragment. This illustrates the patch:

[erb_benchmark.rb]
require 'benchmark'
require 'erb'

class FasterERB < ERB
def set_eoutvar(compiler, eoutvar = '_erbout')
compiler.put_cmd = "#{eoutvar}<<"
compiler.insert_cmd = "#{eoutvar}<<"

   cmd = []
   cmd.push "#{eoutvar} = []"

   compiler.pre_cmd = cmd

   cmd = []
   cmd.push "#{eoutvar}.join"

   compiler.post_cmd = cmd
 end

end

Benchmark.bm(30) do |x|
n = 10
template = %q{got <%= "value" %> }

 erb  = ERB.new template
 frb = FasterERB.new template

 x.report "#{n}k small" do
   (1000 * n).times { erb.result }
 end

 x.report "#{n}k small (fast)" do
   (1000 * n).times { frb.result }
 end

 erb = ERB.new(template * 100)
 frb = FasterERB.new(template * 100)

 x.report "#{n}k large" do
   (1000 * n).times { erb.result }
 end

 x.report "#{n}k large (fast)" do
   (1000 * n).times { frb.result }
 end
 
 if erb.result == frb.result
   puts "outputs are equal"
 end

end

As an example:

% ruby --version
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
% ruby erb_benchmark.rb
user system total real
10k small 0.170000 0.000000 0.170000 ( 0.163556)
10k small (fast) 0.150000 0.000000 0.150000 ( 0.153408)
10k large 6.560000 0.020000 6.580000 ( 6.579351)
10k large (fast) 5.690000 0.010000 5.700000 ( 5.703097)
outputs are equal

I attempted to make up a proper patch but I'm unfamiliar with the repository. I wasn't sure how to run the tests, etc. Obviously the patch simply consists of replacing the set_eoutvar method.

Note that on 1.9.3 it looks like you would also have to force the encoding of the final string.

cmd.push "#{eoutvar}.join.force_encoding(ENCODING)"
=end

Actions #1

Updated by jeremyevans0 (Jeremy Evans) over 4 years ago

  • Tracker changed from Feature to Backport
  • Project changed from Ruby 1.8 to Backport187
  • Description updated (diff)
  • Status changed from Open to Closed
Actions

Also available in: Atom PDF

Like0
Like0