diff options
author | makoto kuwata <kwa@kuwata-lab.com> | 2007-01-10 10:39:41 +0000 |
---|---|---|
committer | makoto kuwata <kwa@kuwata-lab.com> | 2007-01-10 10:39:41 +0000 |
commit | fa38f17239e718b98581731d57888aa2a644891d (patch) | |
tree | bb457a758b0ba84b7cf742dc5df2cb828750d17a /benchmark | |
parent | c39a16254bd9c3d57c9e01f9be7c97ce637c6c2f (diff) | |
download | erubis-fa38f17239e718b98581731d57888aa2a644891d.tar.gz |
- [change] erubybench.rb: option '-A' and '-O' added, '-t' obsoleted
- [change] erubybench.rhtml changed to include 'if-then-else' statement
- [enhance] add 'benchmark/pibench.rb'
Diffstat (limited to 'benchmark')
-rw-r--r-- | benchmark/erubybench.rb | 392 | ||||
-rw-r--r-- | benchmark/erubybench.rhtml | 22 | ||||
-rw-r--r-- | benchmark/pibench.rb | 163 |
3 files changed, 410 insertions, 167 deletions
diff --git a/benchmark/erubybench.rb b/benchmark/erubybench.rb index 0e41e8c..f7fdd59 100644 --- a/benchmark/erubybench.rb +++ b/benchmark/erubybench.rb @@ -27,16 +27,17 @@ defaults = { def usage(defaults) script = File.basename($0) s = <<END -Usage: ruby #{script} [..options..] > /dev/null 2> bench.log +Usage: ruby #{script} [..options..] [..testnames..] > /dev/null 2> bench.log -h : help -n N : number of times to loop (default #{defaults[:ntimes]}) -F erubyfile : eruby filename (default '#{defaults[:filename]}') -f datafile : data filename (default '#{defaults[:datafile]}') - -t testname,.. : target testnames + -A : test all targets -x testname,.. : exclude testnames -T testtype : basic/cache/func -X : expand loop -S : use /dev/null instead of stdout + -O : print output END return s end @@ -46,12 +47,12 @@ end require 'optparse' optparser = OptionParser.new options = {} -['-h', '-n N', '-F erubyfile', '-f datafile', '-t targets', '-x exclude', - '-T testtype', '-X', '-S', '-D'].each do |opt| +['-h', '-n N', '-F erubyfile', '-f datafile', '-A', '-x exclude', + '-T testtype', '-X', '-S', '-O', '-D'].each do |opt| optparser.on(opt) { |val| options[opt[1].chr] = val } end begin - filenames = optparser.parse!(ARGV) + targets = optparser.parse!(ARGV) rescue => ex $stderr.puts "#{command}: #{ex.to_s}" exit(1) @@ -62,11 +63,12 @@ flag_help = options['h'] ntimes = (options['n'] || defaults[:ntimes]).to_i erubyfile = options['F'] || defaults[:erubyfile] datafile = options['f'] || defaults[:datafile] -targets = options['t'] +flag_all = options['A'] testtype = options['T'] excludes = options['x'] $expand = options['X'] ? true : false use_devnull = options['S'] ? true : false +flag_output = options['O'] ? true : false $debug = options['D'] $ntimes = ntimes @@ -94,123 +96,8 @@ data = data.sort_by { |h| h[:code] } ## test definitions -testdefs_str = <<END -- name: ERuby - class: ERuby - code: | - ERuby.import(erubyfile) - compile: | - ERuby::Compiler.new.compile_string(str) - return: null - -- name: ERB - class: ERB - code: | - print ERB.new(File.read(erubyfile)).result(binding()) -# eruby = ERB.new(File.read(erubyfile)) -# print eruby.result(binding()) - compile: | - ERB.new(str).src - return: str - -- name: ErubisEruby - class: Erubis::Eruby - return: str +testdefs = YAML.load(DATA) -- name: ErubisEruby2 - desc: print _buf #, no binding() - class: Erubis::Eruby2 - code: | - #Erubis::Eruby2.new(File.read(erubyfile)).result() - Erubis::Eruby2.new(File.read(erubyfile)).result(binding()) - return: null - skip: yes - -- name: ErubisExprStripped - desc: strip expr code - class: Erubis::ExprStrippedEruby - return: str - skip: yes - -- name: ErubisOptimized - class: Erubis::OptimizedEruby - return: str - skip: yes - -- name: ErubisOptimized2 - class: Erubis::Optimized2Eruby - return: str - skip: yes - -#- name: ErubisArrayBuffer -# class: Erubis::ArrayBufferEruby -# code: | -# Erubis::ArrayBufferEruby.new(File.read(erubyfile)).result(binding()) -# compile: | -# Erubis::ArrayBufferEruby.new(str).src -# return: str -# skip: no - -- name: ErubisStringBuffer - class: Erubis::StringBufferEruby - return: str - skip: no - -- name: ErubisStringIO - class: Erubis::StringIOEruby - return: str - skip: yes - -- name: ErubisSimplified - class: Erubis::SimplifiedEruby - return: str - skip: no - -- name: ErubisStdout - class: Erubis::StdoutEruby - return: null - skip: no - -- name: ErubisStdoutSimplified - class: Erubis::StdoutSimplifiedEruby - return: str - skip: no - -- name: ErubisPrintOut - class: Erubis::PrintOutEruby - return: str - skip: no - -- name: ErubisPrintOutSimplified - class: Erubis::PrintOutSimplifiedEruby - return: str - skip: no - -- name: ErubisTiny - class: Erubis::TinyEruby - return: yes - skip: no - -- name: ErubisTinyStdout - class: Erubis::TinyStdoutEruby - return: null - skip: no - -- name: ErubisTinyPrint - class: Erubis::TinyPrintEruby - return: null - skip: no - -#- name: load -# class: load -# code: | -# load($load_erubyfile) -# compile: null -# return: null -# skip: yes - -END -testdefs = YAML.load(testdefs_str) ## manipulate testdefs.each do |testdef| @@ -222,11 +109,13 @@ end ## select test target -if targets.nil? +if flag_all + # nothing +elsif targets && !targets.empty? + testdefs = targets.collect { |t| testdefs.find { |h| h['name'] == t } }.compact + #testdefs.delete_if { |h| !targets.include?(h['name']) } +else testdefs.delete_if { |h| h['skip'] } -elsif targets.downcase != 'all' - targets = targets.split(/,/) - testdefs.delete_if { |h| !targets.include?(h['name']) } end ## exclude target @@ -234,7 +123,6 @@ if excludes excludes = excluces.split(/,/) testdefs.delete_if { |h| excludes.include?(h['name']) } end - #require 'pp'; pp testdefs @@ -243,7 +131,6 @@ testdefs.each do |h| ## define test functions for each classes s = '' s << "def test_basic_#{h['name']}(erubyfile, data)\n" - s << " $stdout = $outstream\n" if $expand $ntimes.times do s << ' ' << h['code'] #<< "\n" @@ -253,13 +140,11 @@ testdefs.each do |h| s << " #{h['code']}\n" s << " end\n" end - s << " $stdout = STDOUT\n" s << "end\n" #puts s eval s end - ## define view functions for each classes str = File.read(erubyfile) testdefs.each do |h| @@ -330,6 +215,19 @@ testdefs.each do |h| end +## output +if flag_output + testdefs.each do |h| + title = h['class'] + func = 'test_basic_' + h['name'] + puts "## #{h['class']}" + __send__(func, erubyfile, data) + puts + end + exit(0) +end + + ## open /dev/null $outstream = use_devnull ? File.open("/dev/null", 'w') : STDOUT @@ -367,41 +265,215 @@ end ## do benchmark +width = 30 begin - Benchmark.bm(30) do |job| - ## basic test - testdefs.each do |h| - title = h['class'] - func = 'test_basic_' + h['name'] - GC.start - job.report(title) do - __send__(func, erubyfile, data) - end - end if !testtype || testtype == 'basic' - - ## caching function - testdefs.each do |h| - next unless h['compile'] - title = 'cache_' + h['name'] - func = 'test_cache_' + h['name'] - GC.start - job.report(title) do - __send__(func, erubyfile, data) + + ## evaluate + if !testtype || testtype == 'basic' + $stderr.puts "## evaluate" + Benchmark.bm(width) do |job| + ## basic test + testdefs.each do |h| + title = h['class'] + func = 'test_basic_' + h['name'] + GC.start + job.report(title) do + __send__(func, erubyfile, data) + end end - end if !testtype || testtype == 'cache' - - ## view-function test - testdefs.each do |h| - next unless h['compile'] - title = 'func_' + h['name'] - func = 'test_func_' + h['name'] - GC.start - job.report(title) do - __send__(func, data) + end + $stderr.puts + end + + ## caching + if !testtype || testtype == 'cache' + $stderr.puts "## evaluate with cache" + Benchmark.bm(width) do |job| + testdefs.each do |h| + next unless h['compile'] + #title = 'cache_' + h['name'] + title = h['class'] + func = 'test_cache_' + h['name'] + GC.start + job.report(title) do + __send__(func, erubyfile, data) + end end - end if !testtype || testtype == 'func' + end + $stderr.puts + end + ## function + if !testtype || testtype == 'func' + $stderr.puts "## evaluate with function" + Benchmark.bm(width) do |job| + testdefs.each do |h| + next unless h['compile'] + #title = 'func_' + h['name'] + title = h['class'] + func = 'test_func_' + h['name'] + GC.start + job.report(title) do + __send__(func, data) + end + end + end + $stderr.puts end + + #Benchmark.bm(30) do |job| + # ## basic test + # testdefs.each do |h| + # title = h['class'] + # func = 'test_basic_' + h['name'] + # GC.start + # job.report(title) do + # __send__(func, erubyfile, data) + # end + # end if !testtype || testtype == 'basic' + # + # ## caching function + # testdefs.each do |h| + # next unless h['compile'] + # title = 'cache_' + h['name'] + # func = 'test_cache_' + h['name'] + # GC.start + # job.report(title) do + # __send__(func, erubyfile, data) + # end + # end if !testtype || testtype == 'cache' + # + # ## view-function test + # testdefs.each do |h| + # next unless h['compile'] + # title = 'func_' + h['name'] + # func = 'test_func_' + h['name'] + # GC.start + # job.report(title) do + # __send__(func, data) + # end + # end if !testtype || testtype == 'func' + # + #end + ensure $outstream.close() if use_devnull end + +__END__ + +## testdefs + +- name: ERuby + class: ERuby + code: | + ERuby.import(erubyfile) + compile: | + ERuby::Compiler.new.compile_string(str) + return: null + +- name: ERB + class: ERB + code: | + print ERB.new(File.read(erubyfile)).result(binding()) +# eruby = ERB.new(File.read(erubyfile)) +# print eruby.result(binding()) + compile: | + ERB.new(str).src + return: str + +- name: ErubisEruby + class: Erubis::Eruby + return: str + +- name: ErubisEruby2 + desc: print _buf #, no binding() + class: Erubis::Eruby2 + code: | + #Erubis::Eruby2.new(File.read(erubyfile)).result() + Erubis::Eruby2.new(File.read(erubyfile)).result(binding()) + return: null + skip: yes + +- name: ErubisExprStripped + desc: strip expr code + class: Erubis::ExprStrippedEruby + return: str + skip: yes + +- name: ErubisOptimized + class: Erubis::OptimizedEruby + return: str + skip: yes + +- name: ErubisOptimized2 + class: Erubis::Optimized2Eruby + return: str + skip: yes + +#- name: ErubisArrayBuffer +# class: Erubis::ArrayBufferEruby +# code: | +# Erubis::ArrayBufferEruby.new(File.read(erubyfile)).result(binding()) +# compile: | +# Erubis::ArrayBufferEruby.new(str).src +# return: str +# skip: no + +- name: ErubisStringBuffer + class: Erubis::StringBufferEruby + return: str + skip: no + +- name: ErubisStringIO + class: Erubis::StringIOEruby + return: str + skip: yes + +- name: ErubisSimplified + class: Erubis::SimplifiedEruby + return: str + skip: no + +- name: ErubisStdout + class: Erubis::StdoutEruby + return: null + skip: no + +- name: ErubisStdoutSimplified + class: Erubis::StdoutSimplifiedEruby + return: str + skip: yes + +- name: ErubisPrintOut + class: Erubis::PrintOutEruby + return: str + skip: no + +- name: ErubisPrintOutSimplified + class: Erubis::PrintOutSimplifiedEruby + return: str + skip: yes + +- name: ErubisTiny + class: Erubis::TinyEruby + return: yes + skip: no + +- name: ErubisTinyStdout + class: Erubis::TinyStdoutEruby + return: null + skip: yes + +- name: ErubisTinyPrint + class: Erubis::TinyPrintEruby + return: null + skip: yes + +#- name: load +# class: load +# code: | +# load($load_erubyfile) +# compile: null +# return: null +# skip: yes diff --git a/benchmark/erubybench.rhtml b/benchmark/erubybench.rhtml index 0ff5faa..7ef7407 100644 --- a/benchmark/erubybench.rhtml +++ b/benchmark/erubybench.rhtml @@ -40,22 +40,30 @@ thead { </tr> </thead> <tbody> -<% n = 0 %> -<% data.each do |h| %> -<% n += 1 %> -<% klass = n % 2 == 0 ? 'even' : 'odd' %> +<% +n = 0 +data.each do |d| + n += 1 + klass = n % 2 == 0 ? 'even' : 'odd' + %> <tr class="<%= klass %>"> <td style="text-align: center"> <span><%= n %></span> </td> <td> - <a href="/stock/<%= h[:code] %>"><%= h[:code] %></a> + <a href="/stock/<%= d[:code] %>"><%= d[:code] %></a> </td> <td> - <a href="<%= h[:url] %>"><%= h[:name] %></a> + <% if d[:url] %> + <a href="<%= d[:url] %>"><%= d[:name] %></a> + <% else %> + <%= d[:name] %> + <% end %> </td> </tr> -<% end %> +<% +end + %> </tbody> </table> diff --git a/benchmark/pibench.rb b/benchmark/pibench.rb new file mode 100644 index 0000000..95edc78 --- /dev/null +++ b/benchmark/pibench.rb @@ -0,0 +1,163 @@ + +require 'yaml' +require 'benchmark' +require 'eruby' +require 'erb' +require 'erubis' +require 'erubis/tiny' +require 'erubis/engine/enhanced' + + +## default values +ntime = 10000 +filename = 'erubybench.rhtml' +show_code = false +show_output = false +show_help = false + +## parse command-line options +while ARGV[0] && ARGV[0][0] == ?- + option = ARGV.shift + case option + when '-n' + raise "-n: argument required." if ARGV.empty? + ntime = ARGV.shift.to_i + when '-f' + raise "-f: argument required." if ARGV.empty? + filename = ARGV.shift + when '-c' + show_code = true + when '-o' + show_output = true + when '-h' + show_help = true + else + raise "#{option}: unknown option." + end +end + + +## show help +if show_help + script = File.basename($0) + puts "usage: ruby #{script} [-h] [-c] [-o] [-n N] [-f filename] > /dev/null" + puts " -h: show help" + puts " -c: show ruby code" + puts " -o: show output" + puts " -n N: repeat N times in benchmark" + puts " -f file: eRuby file (*.rhtml) for benchmark" + exit +end + + +## load data for benchmark +ydoc = YAML.load_file('erubybench.yaml') +data = [] +ydoc['data'].each do |hash| + #data << hash.inject({}) { |h, t| h[t[0].intern] = t[1]; h } + h = {}; hash.each { |k, v| h[k.intern] = v } ; data << h +end +data = data.sort_by { |h| h[:code] } +#require 'pp'; pp data + + +## eRuby string +input1 = File.read(filename) +input2 = input1.gsub(/<%==\s*(.*?)\s*%>/m, '@{\1}@').gsub(/<%=\s*(.*?)\s*%>/m, '@!{\1}@') +input2 = input2.gsub(/<%(.*?)%>/m, '<?rb\1?>') + + +## procedure objects for benchmark +code = nil +convert_procs = [ + ['eruby', + proc { code = ERuby::Compiler.new.compile_string(input1) } ], +# ['ERB', +# proc { code = ERB.new(input1).src } ], + ['Erubis::Eruby', + proc { code = Erubis::Eruby.new.convert(input1) } ], + ['Erubis::StringBufferEruby', + proc { code = Erubis::StringBufferEruby.new.convert(input1) } ], + ['Erubis::StdoutEruby', + proc { code = Erubis::StdoutEruby.new.convert(input1) } ], + ['Erubis::PI::Eruby', + proc { code = Erubis::PI::Eruby.new.convert(input2) } ], + ['Erubis::TinyEruby', + proc { code = Erubis::TinyEruby.new.convert(input1) } ], + ['Erubis::PI::TinyEruby', + proc { code = Erubis::PI::TinyEruby.new.convert(input2) } ], +] + +evaluate_procs = [ + ['eruby', + proc { ERuby::load(filename) } ], +# ['ERB', +# proc { print ERB.new(input1).result() } ], + ['Erubis::Eruby', + proc { print Erubis::Eruby.new.process(input1, binding()) } ], + ['Erubis::StringBufferEruby', + proc { print Erubis::StringBufferEruby.new.process(input1, binding()) } ], + ['Erubis::StdoutEruby', + proc { Erubis::StdoutEruby.new.process(input1, binding()) } ], + ['Erubis::PI::Eruby', + proc { print Erubis::PI::Eruby.new.process(input2, binding()) } ], + ['Erubis::TinyEruby', + proc { print eval(Erubis::TinyEruby.new.convert(input1)) } ], + ['Erubis::PI::TinyEruby', + proc { print eval(Erubis::PI::TinyEruby.new.convert(input2)) } ], +] + + +## 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 + +## show code or output +if show_code + convert_procs.each do |classname, proc_obj| + puts "---- #{classname} ----" + puts proc_obj.call + end + exit +end + +if show_output + evaluate_procs.each do |classname, proc_obj| + puts "---- #{classname} ---" + proc_obj.call + end + exit +end + + +## do benchmark +width = 30 +$stderr.puts "*** benchmark result of convertion *.rhtml into ruby code" +Benchmark.bm(width) do |x| + GC.start() + convert_procs.each do |classname, proc_obj| + x.report(classname) do + ntime.times(&proc_obj) + end + end +end +$stderr.puts +$stderr.puts "*** benchmark result of evaluation of *.rhtml" +Benchmark.bm(width) do |x| + GC.start() + evaluate_procs.each do |classname, proc_obj| + x.report(classname) do + ntime.times(&proc_obj) + end + end +end |