From 979ec8df5daf6db314b2f17e53b53d269881d6ca Mon Sep 17 00:00:00 2001 From: naruse Date: Mon, 31 Jan 2011 16:11:06 +0000 Subject: * lib/benchmark.rb: fix benchmarck to work with current ruby. patched by Benoit Daloze [ruby-core:33846] [ruby-dev:43143] merged from https://github.com/eregon/ruby/commits/benchmark * lib/benchmark (Report#width): update documentation * lib/benchmark: document the return value of #benchmark and the :list attribute in Report * lib/benchmark (Tms#format): rename variables, use String#% instead of Kernel.format * lib/benchmark: remove undocumented Benchmark::times (an alias of Process::times used twice) * lib/benchmark (#benchmark): use label_width for the caption * lib/benchmark (Tms#initialize): rename variables * lib/benchmark: allow title to not be a String and call #to_s * lib/benchmark (Benchmark#bm): return an Array of the times with the labels * lib/benchmark: correct output for Benchmark#bmbm (remove the extra space) * lib/benchmark: add a few tests for Benchmark::Tms output * lib/benchmark: improve style (enumerators, ljust, unused vars) * lib/benchmark: add spec about output and return value * lib/benchmark: improve basic style and consistency no parenthesis for print and use interpolation instead of printf * lib/benchmark: remove unnecessary conversions and variables * lib/benchmark: correct indentation * lib/benchmark: rename the FMTSTR constant and variable to FORMAT * lib/benchmark: remove useless exception * test/benchmark: remove unused variable warnings git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30747 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/benchmark.rb | 157 +++++++++++++++++++++++++------------------------------ 1 file changed, 70 insertions(+), 87 deletions(-) (limited to 'lib') diff --git a/lib/benchmark.rb b/lib/benchmark.rb index d251fc7e88..052b9add3b 100644 --- a/lib/benchmark.rb +++ b/lib/benchmark.rb @@ -103,10 +103,10 @@ # using the #benchmark method: # # require 'benchmark' -# include Benchmark # we need the CAPTION and FMTSTR constants +# include Benchmark # we need the CAPTION and FORMAT constants # # n = 50000 -# Benchmark.benchmark(" "*7 + CAPTION, 7, FMTSTR, ">total:", ">avg:") do |x| +# Benchmark.benchmark(CAPTION, 7, FORMAT, ">total:", ">avg:") do |x| # tf = x.report("for:") { for i in 1..n; a = "1"; end } # tt = x.report("times:") { n.times do ; a = "1"; end } # tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end } @@ -126,16 +126,13 @@ module Benchmark BENCHMARK_VERSION = "2002-04-25" #:nodoc" - def Benchmark::times() # :nodoc: - Process::times() - end - - # Invokes the block with a Benchmark::Report object, which # may be used to collect and report on the results of individual # benchmark tests. Reserves label_width leading spaces for # labels on each line. Prints _caption_ at the top of the - # report, and uses _fmt_ to format each line. + # report, and uses _format_ to format each line. + # Returns an array of Benchmark::Tms objects. + # # If the block returns an array of # Benchmark::Tms objects, these will be used to format # additional lines of output. If _label_ parameters are @@ -148,10 +145,10 @@ module Benchmark # Example: # # require 'benchmark' - # include Benchmark # we need the CAPTION and FMTSTR constants + # include Benchmark # we need the CAPTION and FORMAT constants # # n = 50000 - # Benchmark.benchmark(" "*7 + CAPTION, 7, FMTSTR, ">total:", ">avg:") do |x| + # Benchmark.benchmark(CAPTION, 7, FORMAT, ">total:", ">avg:") do |x| # tf = x.report("for:") { for i in 1..n; a = "1"; end } # tt = x.report("times:") { n.times do ; a = "1"; end } # tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end } @@ -168,19 +165,19 @@ module Benchmark # >avg: 1.333333 0.011111 1.344444 ( 0.629761) # - def benchmark(caption = "", label_width = nil, fmtstr = nil, *labels) # :yield: report + def benchmark(caption = "", label_width = nil, format = nil, *labels) # :yield: report sync = STDOUT.sync STDOUT.sync = true label_width ||= 0 - fmtstr ||= FMTSTR - raise ArgumentError, "no block" unless iterator? - print caption - results = yield(Report.new(label_width, fmtstr)) + format ||= FORMAT + print ' '*label_width + caption + report = Report.new(label_width, format) + results = yield(report) Array === results and results.grep(Tms).each {|t| - print((labels.shift || t.label || "").ljust(label_width), - t.format(fmtstr)) + print((labels.shift || t.label || "").ljust(label_width), t.format(format)) } STDOUT.sync = sync + report.list end @@ -205,7 +202,7 @@ module Benchmark # def bm(label_width = 0, *labels, &blk) # :yield: report - benchmark(" "*label_width + CAPTION, label_width, FMTSTR, *labels, &blk) + benchmark(CAPTION, label_width, FORMAT, *labels, &blk) end @@ -254,35 +251,24 @@ module Benchmark STDOUT.sync = true # rehearsal - print "Rehearsal " - puts '-'*(width+CAPTION.length - "Rehearsal ".length) - list = [] - job.list.each{|label,item| - print(label.ljust(width)) - res = Benchmark::measure(&item) - print res.format() - list.push res - } - sum = Tms.new; list.each{|i| sum += i} - ets = sum.format("total: %tsec") - printf("%s %s\n\n", - "-"*(width+CAPTION.length-ets.length-1), ets) + puts 'Rehearsal '.ljust(width+CAPTION.length,'-') + ets = job.list.inject(Tms.new) { |sum,(label,item)| + print label.ljust(width) + res = Benchmark.measure(&item) + print res.format + sum + res + }.format("total: %tsec") + print " #{ets}\n\n".rjust(width+CAPTION.length+2,'-') # take - print ' '*width, CAPTION - list = [] - ary = [] - job.list.each{|label,item| - GC::start + print ' '*width + CAPTION + job.list.map { |label,item| + GC.start print label.ljust(width) - res = Benchmark::measure(&item) - print res.format() - ary.push res - list.push [label, res] + Benchmark.measure(&item).tap { |res| print res.format } + }.tap { + STDOUT.sync = sync } - - STDOUT.sync = sync - ary end # @@ -290,9 +276,9 @@ module Benchmark # Benchmark::Tms object. # def measure(label = "") # :yield: - t0, r0 = Benchmark.times, Time.now + t0, r0 = Process.times, Time.now yield - t1, r1 = Benchmark.times, Time.now + t1, r1 = Process.times, Time.now Benchmark::Tms.new(t1.utime - t0.utime, t1.stime - t0.stime, t1.cutime - t0.cutime, @@ -307,11 +293,10 @@ module Benchmark def realtime(&blk) # :yield: r0 = Time.now yield - r1 = Time.now - r1.to_f - r0.to_f + Time.now - r0 end - + module_function :benchmark, :measure, :realtime, :bm, :bmbm # # A Job is a sequence of labelled blocks to be processed by the @@ -335,10 +320,10 @@ module Benchmark # def item(label = "", &blk) # :yield: raise ArgumentError, "no block" unless block_given? - label += ' ' + label = label.to_s w = label.length @width = w if @width < w - @list.push [label, blk] + @list << [label, blk] self end @@ -347,14 +332,10 @@ module Benchmark # An array of 2-element arrays, consisting of label and block pairs. attr_reader :list - # Length of the widest label in the #list, plus one. + # Length of the widest label in the #list. attr_reader :width end - module_function :benchmark, :measure, :realtime, :bm, :bmbm - - - # # This class is used by the Benchmark.benchmark and Benchmark.bm methods. # It is of little direct interest to the user. @@ -364,26 +345,29 @@ module Benchmark # Returns an initialized Report instance. # Usually, one doesn't call this method directly, as new # Report objects are created by the #benchmark and #bm methods. - # _width_ and _fmtstr_ are the label offset and + # _width_ and _format_ are the label offset and # format string used by Tms#format. # - def initialize(width = 0, fmtstr = nil) - @width, @fmtstr = width, fmtstr + def initialize(width = 0, format = nil) + @width, @format, @list = width, format, [] end # # Prints the _label_ and measured time for the block, - # formatted by _fmt_. See Tms#format for the + # formatted by _format_. See Tms#format for the # formatting rules. # - def item(label = "", *fmt, &blk) # :yield: - print label.ljust(@width) - res = Benchmark::measure(&blk) - print res.format(@fmtstr, *fmt) + def item(label = "", *format, &blk) # :yield: + print label.to_s.ljust(@width) + @list << res = Benchmark.measure(label, &blk) + print res.format(@format, *format) res end alias report item + + # An array of Benchmark::Tms objects representing each item. + attr_reader :list end @@ -394,7 +378,7 @@ module Benchmark # class Tms CAPTION = " user system total real\n" - FMTSTR = "%10.6u %10.6y %10.6t %10.6r\n" + FORMAT = "%10.6u %10.6y %10.6t %10.6r\n" # User CPU time attr_reader :utime @@ -419,13 +403,12 @@ module Benchmark # # Returns an initialized Tms object which has - # _u_ as the user CPU time, _s_ as the system CPU time, - # _cu_ as the children's user CPU time, _cs_ as the children's - # system CPU time, _real_ as the elapsed real time and _l_ - # as the label. + # _utime_ as the user CPU time, _stime_ as the system CPU time, + # _cutime_ as the children's user CPU time, _cstime_ as the children's + # system CPU time, _real_ as the elapsed real time and _label_ as the label. # - def initialize(u = 0.0, s = 0.0, cu = 0.0, cs = 0.0, real = 0.0, l = nil) - @utime, @stime, @cutime, @cstime, @real, @label = u, s, cu, cs, real, l + def initialize(utime = 0.0, stime = 0.0, cutime = 0.0, cstime = 0.0, real = 0.0, label = nil) + @utime, @stime, @cutime, @cstime, @real, @label = utime, stime, cutime, cstime, real, label.to_s @total = @utime + @stime + @cutime + @cstime end @@ -434,14 +417,14 @@ module Benchmark # Tms object, plus the time required to execute the code block (_blk_). # def add(&blk) # :yield: - self + Benchmark::measure(&blk) + self + Benchmark.measure(&blk) end # # An in-place version of #add. # def add!(&blk) - t = Benchmark::measure(&blk) + t = Benchmark.measure(&blk) @utime = utime + t.utime @stime = stime + t.stime @cutime = cutime + t.cutime @@ -492,19 +475,19 @@ module Benchmark # %r:: Replaced by the elapsed real time, as reported by Tms#real # %n:: Replaced by the label string, as reported by Tms#label (Mnemonic: n of "*n*ame") # - # If _fmtstr_ is not given, FMTSTR is used as default value, detailing the + # If _format_ is not given, FORMAT is used as default value, detailing the # user, system and real elapsed time. # - def format(arg0 = nil, *args) - fmtstr = (arg0 || FMTSTR).dup - fmtstr.gsub!(/(%[-+\.\d]*)n/){"#{$1}s" % label} - fmtstr.gsub!(/(%[-+\.\d]*)u/){"#{$1}f" % utime} - fmtstr.gsub!(/(%[-+\.\d]*)y/){"#{$1}f" % stime} - fmtstr.gsub!(/(%[-+\.\d]*)U/){"#{$1}f" % cutime} - fmtstr.gsub!(/(%[-+\.\d]*)Y/){"#{$1}f" % cstime} - fmtstr.gsub!(/(%[-+\.\d]*)t/){"#{$1}f" % total} - fmtstr.gsub!(/(%[-+\.\d]*)r/){"(#{$1}f)" % real} - arg0 ? Kernel::format(fmtstr, *args) : fmtstr + def format(format = nil, *args) + str = (format || FORMAT).dup + str.gsub!(/(%[-+\.\d]*)n/) { "#{$1}s" % label } + str.gsub!(/(%[-+\.\d]*)u/) { "#{$1}f" % utime } + str.gsub!(/(%[-+\.\d]*)y/) { "#{$1}f" % stime } + str.gsub!(/(%[-+\.\d]*)U/) { "#{$1}f" % cutime } + str.gsub!(/(%[-+\.\d]*)Y/) { "#{$1}f" % cstime } + str.gsub!(/(%[-+\.\d]*)t/) { "#{$1}f" % total } + str.gsub!(/(%[-+\.\d]*)r/) { "(#{$1}f)" % real } + format ? str % args : str end # @@ -549,7 +532,7 @@ module Benchmark CAPTION = Benchmark::Tms::CAPTION # The default format string used to display times. See also Benchmark::Tms#format. - FMTSTR = Benchmark::Tms::FMTSTR + FORMAT = Benchmark::Tms::FORMAT end if __FILE__ == $0 @@ -557,15 +540,15 @@ if __FILE__ == $0 n = ARGV[0].to_i.nonzero? || 50000 puts %Q([#{n} times iterations of `a = "1"']) - benchmark(" " + CAPTION, 7, FMTSTR) do |x| - x.report("for:") {for _ in 1..n; _ = "1"; end} # Benchmark::measure + benchmark(" " + CAPTION, 7, FORMAT) do |x| + x.report("for:") {for _ in 1..n; _ = "1"; end} # Benchmark.measure x.report("times:") {n.times do ; _ = "1"; end} x.report("upto:") {1.upto(n) do ; _ = "1"; end} end benchmark do [ - measure{for _ in 1..n; _ = "1"; end}, # Benchmark::measure + measure{for _ in 1..n; _ = "1"; end}, # Benchmark.measure measure{n.times do ; _ = "1"; end}, measure{1.upto(n) do ; _ = "1"; end} ] -- cgit v1.2.3