diff --git a/ChangeLog b/ChangeLog index 3d029dd866..509251f69c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Thu Sep 27 15:44:51 2007 Koichi Sasada + + * benchmark/driver.rb: added. + + * common.mk: fix to use above driver. + + * benchmark/prepare_so_count_words.rb: added. + + * benchmark/bm_so_count_words.rb: fix benchmark process. + Thu Sep 27 15:42:34 2007 Koichi Sasada * ext/fiber/fiber.c: modify prototype declaration. diff --git a/benchmark/bm_so_count_words.rb b/benchmark/bm_so_count_words.rb index a208004a9a..65f6337a4a 100644 --- a/benchmark/bm_so_count_words.rb +++ b/benchmark/bm_so_count_words.rb @@ -8,11 +8,12 @@ input = open(File.join(File.dirname($0), 'wc.input'), 'rb') nl = nw = nc = 0 while true - data = (input.read(4096) or break) << (input.gets || "") + tmp = input.read(4096) or break + data = tmp << (input.gets || "") nc += data.length nl += data.count("\n") ((data.strip! || data).tr!("\n", " ") || data).squeeze! - #nw += data.count(" ") + 1 + nw += data.count(" ") + 1 end # STDERR.puts "#{nl} #{nw} #{nc}" diff --git a/benchmark/bmx_temp.rb b/benchmark/bmx_temp.rb index e69de29bb2..2b78092793 100644 --- a/benchmark/bmx_temp.rb +++ b/benchmark/bmx_temp.rb @@ -0,0 +1,5 @@ +str = '*' * 1_000_000 + +1.times{ + str.split('*').size +} diff --git a/benchmark/driver.rb b/benchmark/driver.rb new file mode 100644 index 0000000000..7837e8b728 --- /dev/null +++ b/benchmark/driver.rb @@ -0,0 +1,170 @@ +# +# Ruby Benchmark driver +# + +require 'optparse' +require 'benchmark' +require 'pp' + +class BenchmarkDriver + def self.benchmark(opt) + driver = self.new(opt[:execs], opt[:dir], opt) + begin + driver.run + ensure + driver.show_results + end + end + + def initialize execs, dir, opt = {} + @execs = execs.map{|e| + e.strip! + next if e.empty? + + v = `#{e} -v`.chomp + v.sub!(' patchlevel 0', '') + [e, v] + }.compact + + @dir = dir + @repeat = opt[:repeat] || 1 + @repeat = 1 if @repeat < 1 + @pattern = opt[:pattern] || nil + @verbose = opt[:quiet] ? false : (opt[:verbose] || false) + @loop_wl1 = @loop_wl2 = nil + @opt = opt + + # [[name, [[r-1-1, r-1-2, ...], [r-2-1, r-2-2, ...]]], ...] + @results = [] + + if @verbose + puts Time.now + @execs.each_with_index{|(e, v), i| + puts "target #{i}: #{v}" + } + end + end + + def show_results + if @verbose + puts '-----------------------------------------------------------' + puts 'raw data:' + pp @results + end + + puts '-----------------------------------------------------------' + puts 'benchmark results:' + if @verbose and @repeat > 1 + puts "minimum results in each #{@repeat} measurements." + end + puts "name\t#{@execs.map{|(e, v)| v}.join("\t")}" + @results.each{|v, result| + rets = [] + s = nil + result.each_with_index{|e, i| + r = e.min + case v + when /^vm1_/ + if @loop_wl1 + r -= @loop_wl1[i] + s = '*' + end + when /^vm2_/ + if @loop_wl2 + r -= @loop_wl2[i] + s = '*' + end + end + rets << sprintf("%.3f", r) + } + puts "#{v}#{s}\t#{rets.join("\t")}" + } + + end + + def run + Dir.glob(File.join(@dir, 'bm*.rb')){|file| + next if @pattern && /#{@pattern}/ !~ File.basename(file) + + if /bm_vm1_/ =~ file and !@loop_wl1 + r = measure_file(File.join(File.dirname(file), 'bm_loop_whileloop.rb')) + @loop_wl1 = r[1].map{|e| e.min} + elsif /bm_vm1_/ =~ file and !@loop_wl2 + r = measure_file(File.join(File.dirname(file), 'bm_loop_whileloop2.rb')) + @loop_wl2 = r[1].map{|e| e.min} + end + + measure_file(file) + } + end + + def measure_file file + name = File.basename(file, '.rb').sub(/^bm_/, '') + prepare_file = File.join(File.dirname(file), "prepare_#{name}.rb") + load prepare_file if FileTest.exist?(prepare_file) + + if @verbose + puts '-----------------------------------------------------------' + puts name + puts File.read(file) + puts + end + + result = [name] + result << @execs.map{|(e, v)| + (0...@repeat).map{ + print "#{v}\t" if @verbose + STDOUT.flush + m = measure e, file + puts "#{m}" if @verbose + m + } + } + @results << result + result + end + + def measure executable, file + m = Benchmark.measure{ + `#{executable} #{file}` + } + + if $? != 0 + raise "Benchmark process exited with abnormal status (#{$?})" + end + m.real + end +end + +if __FILE__ == $0 + opt = { + :execs => ['ruby'], + :dir => './', + :repeat => 1, + } + parser = OptionParser.new{|o| + o.on('-e', '--executables [EXECUTABLES]', + 'Specify benchmark targets ("exec1; exec2; exec3, ...")'){|e| + opt[:execs] = e.split(/;/) + } + o.on('-d', '--directory [DIRECTORY]'){|d| + opt[:dir] = d + } + o.on('-p', '--pattern [PATTERN]', "Benchmark name pattern"){|p| + opt[:pattern] = p + } + o.on('-n', '--repeat-num [NUM]', "Repeat count"){|n| + opt[:repeat] = n.to_i + } + o.on('-q', '--quiet'){|q| + opt[:quiet] = q + } + o.on('-v', '--verbose'){|v| + opt[:verbose] = v + } + } + + parser.parse!(ARGV) + BenchmarkDriver.benchmark(opt) +end + diff --git a/benchmark/prepare_so_count_words.rb b/benchmark/prepare_so_count_words.rb new file mode 100644 index 0000000000..54ea72b8ed --- /dev/null +++ b/benchmark/prepare_so_count_words.rb @@ -0,0 +1,15 @@ +# prepare 'wc.input' + +def prepare_wc_input + wcinput = File.join(File.dirname($0), 'wc.input') + wcbase = File.join(File.dirname($0), 'wc.input.base') + unless FileTest.exist?(wcinput) + data = File.read(wcbase) + 13.times{ + data << data + } + open(wcinput, 'w'){|f| f.write data} + end +end + +prepare_wc_input diff --git a/common.mk b/common.mk index f19da4b118..702e8ed371 100644 --- a/common.mk +++ b/common.mk @@ -595,8 +595,6 @@ blockinlining.$(OBJEXT): {$(VPATH)}blockinlining.c \ id.$(OBJEXT): {$(VPATH)}id.c {$(VPATH)}ruby.h prelude.$(OBJEXT): {$(VPATH)}prelude.c {$(VPATH)}ruby.h {$(VPATH)}vm_core.h -MATZRUBY = $(MATZRUBYDIR)ruby - INSNS = opt_sc.inc optinsn.inc optunifs.inc insns.inc \ vmtc.inc vm.inc @@ -637,16 +635,6 @@ docs: ## -compare: miniruby$(EXEEXT) PHONY - @$(MATZRUBY) -v -I$(srcdir) $(srcdir)/test.rb - @$(MINIRUBY) -v -I$(srcdir) $(srcdir)/test.rb - -compare-test: miniruby$(EXEEXT) $(PROGRAM) PHONY - $(RUNRUBY) -I$(srcdir) $(srcdir)/yarvtest/runner.rb $(OPT) ruby=$(MINIRUBY) matzruby=$(MATZRUBY) - -compare-test-each: miniruby$(EXEEXT) $(PROGRAM) PHONY - $(RUNRUBY) -I$(srcdir) $(srcdir)/yarvtest/test_$(ITEM).rb $(OPT) ruby=$(MINIRUBY) matzruby=$(MATZRUBY) - run: miniruby$(EXEEXT) PHONY $(MINIRUBY) -I$(srcdir)/lib $(srcdir)/test.rb $(RUNOPT) @@ -656,14 +644,24 @@ runruby: $(PROGRAM) PHONY parse: miniruby$(EXEEXT) PHONY $(MINIRUBY) $(srcdir)/tool/parse.rb $(srcdir)/test.rb +COMPARE_RUBY = $(BASERUBY) +ITEM = +OPTS = + benchmark: $(PROGRAM) PHONY - $(RUNRUBY) $(srcdir)/benchmark/run.rb $(OPT) $(ITEMS) --ruby='./$(PROGRAM) -I$(srcdir)/lib' --matzruby=$(MATZRUBY) + $(BASERUBY) $(srcdir)/benchmark/driver.rb -v \ + --executables="$(COMPARE_RUBY); $(RUNRUBY)" \ + --pattern='bm_' --directory=$(srcdir)/benchmark $(OPTS) benchmark-each: $(PROGRAM) PHONY - $(RUNRUBY) $(srcdir)/benchmark/run.rb bm_$(ITEM) $(OPT) --ruby='./$(PROGRAM) -I$(srcdir)/lib' --matzruby=$(MATZRUBY) + $(BASERUBY) $(srcdir)/benchmark/driver.rb -v \ + --executables="$(COMPARE_RUBY); $(RUNRUBY)" \ + --pattern=$(ITEM) --directory=$(srcdir)/benchmark $(OPTS) tbench: $(PROGRAM) PHONY - $(RUNRUBY) $(srcdir)/benchmark/run.rb bmx $(OPT) --ruby=./$(PROGRAM) --matzruby=$(MATZRUBY) --opts=-I$(srcdir)/lib + $(BASERUBY) $(srcdir)/benchmark/driver.rb -v \ + --executables="$(COMPARE_RUBY); $(RUNRUBY)" \ + --pattern='bmx_' --directory=$(srcdir)/benchmark $(OPTS) aotc: $(PROGRAM) PHONY ./$(PROGRAM) -I$(srcdir)/lib $(srcdir)/bin/ruby2cext $(srcdir)/test.rb