summaryrefslogtreecommitdiff
path: root/benchmark
diff options
context:
space:
mode:
authormakoto kuwata <kwa@kuwata-lab.com>2007-01-10 10:39:41 +0000
committermakoto kuwata <kwa@kuwata-lab.com>2007-01-10 10:39:41 +0000
commitfa38f17239e718b98581731d57888aa2a644891d (patch)
treebb457a758b0ba84b7cf742dc5df2cb828750d17a /benchmark
parentc39a16254bd9c3d57c9e01f9be7c97ce637c6c2f (diff)
downloaderubis-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.rb392
-rw-r--r--benchmark/erubybench.rhtml22
-rw-r--r--benchmark/pibench.rb163
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