From 547261f1fb3a85a262a7c918db74732228d6e3c9 Mon Sep 17 00:00:00 2001 From: makoto kuwata Date: Tue, 15 May 2007 13:36:41 +0000 Subject: - [enhance] add 'benchmark/bench.rb' and 'benchmark/templates/*' --- benchmark/bench.rb | 306 +++++++++++++++++++++++++++++++++ benchmark/templates/_footer.html | 4 + benchmark/templates/_header.html | 52 ++++++ benchmark/templates/bench_erb.rhtml | 29 ++++ benchmark/templates/bench_erubis.rhtml | 29 ++++ benchmark/templates/bench_eruby.rhtml | 29 ++++ 6 files changed, 449 insertions(+) create mode 100644 benchmark/bench.rb create mode 100644 benchmark/templates/_footer.html create mode 100644 benchmark/templates/_header.html create mode 100644 benchmark/templates/bench_erb.rhtml create mode 100644 benchmark/templates/bench_erubis.rhtml create mode 100644 benchmark/templates/bench_eruby.rhtml (limited to 'benchmark') diff --git a/benchmark/bench.rb b/benchmark/bench.rb new file mode 100644 index 0000000..e7a0b04 --- /dev/null +++ b/benchmark/bench.rb @@ -0,0 +1,306 @@ +#!/usr/bin/env ruby + +### +### $Rev$ +### $Release: $ +### $Copyright$ +### + +require 'erb' +require 'erubis' +require 'erubis/tiny' +require 'erubis/engine/enhanced' +require 'yaml' +require 'cgi' +include ERB::Util + +begin + require 'eruby' +rescue LoadError + ERuby = nil +end + +def File.write(filename, content) + File.open(filename, 'w') { |f| f.write(content) } +end + + +## change benchmark library to use $stderr instead of $stdout +require 'benchmark' +module Benchmark + class Report + def print(*args) + $stderr.print(*args) + end + end + module_function + def print(*args) + $stderr.print(*args) + end +end + + +class BenchmarkApplication + + TARGETS = %w[eruby + ERB ERB(cached) + Erubis::Eruby Erubis::Eruby(cached) + Erubis::FastEruby Erubis::FastEruby(cached) + Erubis::TinyEruby + Erubis::ArrayBufferEruby + Erubis::PrintOutEruby + Erubis::StdoutEruby + ] + + def initialize(ntimes, context, targets=nil, params={}) + @ntimes = ntimes + @context = context + @targets = targets && !targets.empty? ? targets : TARGETS.dup + @testmode = params[:testmode] || 'execute' + @erubyfile = params[:erubyfile] || 'erubybench.rhtml' + @printout = params[:printout] || false + end + + attr_accessor :ntimes, :targets + attr_accessor :testmode, :erubyfile, :contextfile, :printout + + def context2code(context, varname='context') + s = '' + context.each { |k, | s << "#{k} = #{varname}[#{k.inspect}]; " } + return s + end + + def perform_benchmark + width = 30 + $stderr.puts "*** ntimes=#{@ntimes}, testmode=#{@testmode}" + Benchmark.bm(width) do |job| + for target in @targets do + method = "#{@testmode}_#{target.gsub(/::|-|\(/, '_').gsub(/\)/, '').downcase}" + #$stderr.puts "*** debug: method=#{method.inspect}" + next unless self.respond_to?(method) + filename = "bench_#{(target =~ /^(\w+)/) && $1.downcase}.rhtml" + title = target + output = nil + job.report(title) do + output = self.__send__(method, filename, @context) + end + File.write("output.#{target.gsub(/[^\w]/,'')}", output) if @printout && output && !output.empty? + end + end + end + + ## + + def execute_eruby(filename, context) + return unless ERuby + eval context2code(context) + @ntimes.times do + ERuby.import(filename) + end + return nil + end + + def execute_erb(filename, context) + eval context2code(context) + output = nil + @ntimes.times do + eruby = ERB.new(File.read(filename)) + output = eruby.result(binding()) + print output + end + return output + end + + def execute_erb_cached(filename, context) + eval context2code(context) + output = nil + cachefile = filename + '.cache' + File.unlink(cachefile) if test(?f, cachefile) + @ntimes.times do + if !test(?f, cachefile) || File.mtime(filename) > File.mtime(cachefile) + eruby = ERB.new(File.read(filename)) + File.write(cachefile, eruby.src) + else + eruby = ERB.new('') + #eruby.src = File.read(cachefile) + eruby.instance_variable_set("@src", File.read(cachefile)) + end + output = eruby.result(binding()) + print output + end + return output + end + + ## no cached + for klass in %w[Eruby FastEruby TinyEruby ArrayBufferEruby PrintOutEruby StdoutEruby] do + s = <<-END + def execute_erubis_#{klass.downcase}(filename, context) + eval context2code(context) + output = nil + @ntimes.times do + eruby = Erubis::#{klass}.new(File.read(filename)) + output = eruby.result(binding()) + print output + end + return output + end + END + eval s + end + + ## cached + for klass in %w[Eruby FastEruby] do + s = <<-END + def execute_erubis_#{klass.downcase}_cached(filename, context) + eval context2code(context) + cachefile = filename + '.cache' + File.unlink(cachefile) if test(?f, cachefile) + output = nil + @ntimes.times do + eruby = Erubis::#{klass}.load_file(filename) + output = eruby.result(binding()) + print output + end + savefile = cachefile.sub(/\\.cache$/, '.#{klass.downcase}.cache') + File.rename(cachefile, savefile) + return output + end + END + eval s + end + + ## + + def convert_eruby(filename, context) + return unless ERuby + eval context2code(context) + output = nil + @ntimes.times do + output = ERuby::Compiler.new.compile_string(File.read(filename)) + end + return output + end + + def convert_erb(filename, context) + eval context2code(context) + output = nil + @ntimes.times do + eruby = ERB.new(File.read(filename)) + output = eruby.src + end + return output + end + + for klass in %w[Eruby FastEruby TinyEruby] + s = <<-END + def convert_erubis_#{klass.downcase}(filename, context) + eval context2code(context) + output = nil + @ntimes.times do + eruby = Erubis::#{klass}.new(File.read(filename)) + output = eruby.src + end + return output + end + END + eval s + end + +end + + +require 'optparse' + +class MainApplication + + def parse_argv(argv=ARGV) + optparser = OptionParser.new + options = {} + ['-h', '-n N', '-t erubyfile', '-f contextfile', '-A', '-e', + '-x exclude', '-m testmode', '-X', '-p', '-D'].each do |opt| + optparser.on(opt) { |val| options[opt[1].chr] = val } + end + begin + targets = optparser.parse!(argv) + rescue => ex + $stderr.puts "#{@script}: #{ex.to_s}" + exit(1) + end + return options, targets + end + + def execute + @script = File.basename($0) + ntimes = 1000 + targets = BenchmarkApplication::TARGETS.dup + testmode = 'execute' + contextfile = 'erubybench.yaml' + # + options, args = parse_argv(ARGV) + ntimes = options['n'].to_i if options['n'] + targets = args if args && !args.empty? + targets = targets - options['x'].split(/,/) if options['x'] + testmode = options['m'] if options['m'] + contextfile = options['f'] if options['f'] + erubyfile = options['t'] if options['t'] + # + if options['h'] + $stderr.puts "Usage: ruby #{@script} [..options..] [..targets..]" + $stderr.puts " -h : help" + $stderr.puts " -n N : loop N times" + $stderr.puts " -f datafile : context data filename (*.yaml)" + $stderr.puts " -x exclude : exclude target name" + $stdout.puts " -m testmode : 'execute' or 'convert' (default 'execute')" + $stderr.puts " -p : print output to file (filename: 'output.TARGETNAME')" + return + end + # + #if ! options['t'] + for item in %w[eruby erb erubis] + fname = "bench_#{item}.rhtml" + header = File.read("templates/_header.html") + #body = File.read("templates/#{erubyfile}") + body = File.read("templates/#{fname}") + footer = File.read("templates/_footer.html") + content = header + body + footer + File.write(fname, content) + end + # + if options['e'] # escape + tuples = [ + [ 'bench_eruby.rhtml', '<%= CGI.escapeHTML((\1).to_s) %>' ], + [ 'bench_erb.rhtml', '<%=h \1 %>' ], + [ 'bench_erubis.rhtml', '<%== \1 %>' ], + ] + for fname, replace in tuples + content = File.read(fname).gsub(/<%= ?(.*?) ?%>/, replace) + File.write(fname, content) + end + targets.delete('Erubis::TinyEruby') ## because TinyEruby doesn't support '<%== =>' + end + # + context = YAML.load_file(contextfile) + # + params = { + :printout=>options['p'], + :testmode=>testmode, + } + app = BenchmarkApplication.new(ntimes, context, targets, params) + app.perform_benchmark() + end + +end + + +if __FILE__ == $0 + + ## open /dev/null + $stdout = File.open('/dev/null', 'w') + at_exit do + $stdout.close() + end + + ## start benchmark + MainApplication.new().execute() + +end diff --git a/benchmark/templates/_footer.html b/benchmark/templates/_footer.html new file mode 100644 index 0000000..3ae6d4d --- /dev/null +++ b/benchmark/templates/_footer.html @@ -0,0 +1,4 @@ + + + + diff --git a/benchmark/templates/_header.html b/benchmark/templates/_header.html new file mode 100644 index 0000000..cbab956 --- /dev/null +++ b/benchmark/templates/_header.html @@ -0,0 +1,52 @@ + + + + + Stock Prices + + + + + + + + + + + + +

Stock Prices

+ + + + + + + diff --git a/benchmark/templates/bench_erb.rhtml b/benchmark/templates/bench_erb.rhtml new file mode 100644 index 0000000..3dde9d5 --- /dev/null +++ b/benchmark/templates/bench_erb.rhtml @@ -0,0 +1,29 @@ + +<% +n = 0 +for item in list + n += 1 + %> + + + + + +<% if item['change'] < 0.0 %> + + +<% else %> + + +<% end %> + +<% +end + %> + diff --git a/benchmark/templates/bench_erubis.rhtml b/benchmark/templates/bench_erubis.rhtml new file mode 100644 index 0000000..3dde9d5 --- /dev/null +++ b/benchmark/templates/bench_erubis.rhtml @@ -0,0 +1,29 @@ + +<% +n = 0 +for item in list + n += 1 + %> + + + + + +<% if item['change'] < 0.0 %> + + +<% else %> + + +<% end %> + +<% +end + %> + diff --git a/benchmark/templates/bench_eruby.rhtml b/benchmark/templates/bench_eruby.rhtml new file mode 100644 index 0000000..3dde9d5 --- /dev/null +++ b/benchmark/templates/bench_eruby.rhtml @@ -0,0 +1,29 @@ + +<% +n = 0 +for item in list + n += 1 + %> + + + + + +<% if item['change'] < 0.0 %> + + +<% else %> + + +<% end %> + +<% +end + %> + -- cgit v1.2.1
#symbolnamepricechangeratio
<%= n %> + <%= item['symbol'] %> + + <%= item['name'] %> + + <%= item['price'] %> + <%= item['change'] %><%= item['ratio'] %><%= item['change'] %><%= item['ratio'] %>
<%= n %> + <%= item['symbol'] %> + + <%= item['name'] %> + + <%= item['price'] %> + <%= item['change'] %><%= item['ratio'] %><%= item['change'] %><%= item['ratio'] %>
<%= n %> + <%= item['symbol'] %> + + <%= item['name'] %> + + <%= item['price'] %> + <%= item['change'] %><%= item['ratio'] %><%= item['change'] %><%= item['ratio'] %>