123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- #!/usr/bin/env ruby
- ###
- ### $Release: 2.7.0 $
- ### copyright(c) 2006-2011 kuwata-lab.com all rights reserved.
- ###
- 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)
- list = context['list']
- @ntimes.times do
- ERuby.import(filename)
- end
- return nil
- end
- def execute_erb(filename, context)
- #eval context2code(context)
- list = context['list']
- 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)
- list = context['list']
- 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)
- list = context['list']
- 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)
- list = context['list']
- 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)
- list = context['list']
- 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)
- list = context['list']
- 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)
- list = context['list']
- 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 = 'bench_context.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
|