summaryrefslogtreecommitdiff
path: root/benchmark
diff options
context:
space:
mode:
authormakoto kuwata <kwa@kuwata-lab.com>2007-05-15 13:36:41 +0000
committermakoto kuwata <kwa@kuwata-lab.com>2007-05-15 13:36:41 +0000
commit547261f1fb3a85a262a7c918db74732228d6e3c9 (patch)
tree2e548a00f7dbbb2f0938d87ba11cb972b36ce61f /benchmark
parent01343ebc30691865702fb8c426575ba7b5046342 (diff)
downloaderubis-547261f1fb3a85a262a7c918db74732228d6e3c9.tar.gz
- [enhance] add 'benchmark/bench.rb' and 'benchmark/templates/*'
Diffstat (limited to 'benchmark')
-rw-r--r--benchmark/bench.rb306
-rw-r--r--benchmark/templates/_footer.html4
-rw-r--r--benchmark/templates/_header.html52
-rw-r--r--benchmark/templates/bench_erb.rhtml29
-rw-r--r--benchmark/templates/bench_erubis.rhtml29
-rw-r--r--benchmark/templates/bench_eruby.rhtml29
6 files changed, 449 insertions, 0 deletions
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 @@
+ </table>
+
+ </body>
+</html>
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <title>Stock Prices</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
+ <link rel="shortcut icon" href="/images/favicon.ico" />
+ <link rel="stylesheet" type="text/css" href="/css/style.css" media="all" />
+ <script type="text/javascript" src="/js/util.js"></script>
+ <style type="text/css">
+ /*<![CDATA[*/
+
+body {
+ color: #333333;
+ line-height: 150%;
+}
+
+thead {
+ font-weight: bold;
+ background-color: #CCCCCC;
+}
+
+.odd {
+ background-color: #FFCCCC;
+}
+
+.even {
+ background-color: #CCCCFF;
+}
+
+.minus {
+ color: #FF0000;
+}
+
+ /*]]>*/
+ </style>
+
+ </head>
+
+ <body>
+
+ <h1>Stock Prices</h1>
+
+ <table>
+ <thead>
+ <tr>
+ <th>#</th><th>symbol</th><th>name</th><th>price</th><th>change</th><th>ratio</th>
+ </tr>
+ </thead>
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 @@
+ <tbody>
+<%
+n = 0
+for item in list
+ n += 1
+ %>
+ <tr class="<%= n % 2 == 0 ? 'even' : 'odd' %>">
+ <td style="text-align: center"><%= n %></td>
+ <td>
+ <a href="/stocks/<%= item['symbol'] %>"><%= item['symbol'] %></a>
+ </td>
+ <td>
+ <a href="<%= item['url'] %>"><%= item['name'] %></a>
+ </td>
+ <td>
+ <strong><%= item['price'] %></strong>
+ </td>
+<% if item['change'] < 0.0 %>
+ <td class="minus"><%= item['change'] %></td>
+ <td class="minus"><%= item['ratio'] %></td>
+<% else %>
+ <td><%= item['change'] %></td>
+ <td><%= item['ratio'] %></td>
+<% end %>
+ </tr>
+<%
+end
+ %>
+ </tbody>
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 @@
+ <tbody>
+<%
+n = 0
+for item in list
+ n += 1
+ %>
+ <tr class="<%= n % 2 == 0 ? 'even' : 'odd' %>">
+ <td style="text-align: center"><%= n %></td>
+ <td>
+ <a href="/stocks/<%= item['symbol'] %>"><%= item['symbol'] %></a>
+ </td>
+ <td>
+ <a href="<%= item['url'] %>"><%= item['name'] %></a>
+ </td>
+ <td>
+ <strong><%= item['price'] %></strong>
+ </td>
+<% if item['change'] < 0.0 %>
+ <td class="minus"><%= item['change'] %></td>
+ <td class="minus"><%= item['ratio'] %></td>
+<% else %>
+ <td><%= item['change'] %></td>
+ <td><%= item['ratio'] %></td>
+<% end %>
+ </tr>
+<%
+end
+ %>
+ </tbody>
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 @@
+ <tbody>
+<%
+n = 0
+for item in list
+ n += 1
+ %>
+ <tr class="<%= n % 2 == 0 ? 'even' : 'odd' %>">
+ <td style="text-align: center"><%= n %></td>
+ <td>
+ <a href="/stocks/<%= item['symbol'] %>"><%= item['symbol'] %></a>
+ </td>
+ <td>
+ <a href="<%= item['url'] %>"><%= item['name'] %></a>
+ </td>
+ <td>
+ <strong><%= item['price'] %></strong>
+ </td>
+<% if item['change'] < 0.0 %>
+ <td class="minus"><%= item['change'] %></td>
+ <td class="minus"><%= item['ratio'] %></td>
+<% else %>
+ <td><%= item['change'] %></td>
+ <td><%= item['ratio'] %></td>
+<% end %>
+ </tr>
+<%
+end
+ %>
+ </tbody>