summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-31 16:11:06 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-31 16:11:06 +0000
commit979ec8df5daf6db314b2f17e53b53d269881d6ca (patch)
treeccfe52c1389f3fea5b872b20d7c997b93ea7bc76 /lib
parent6b06ba0c05cf966fa495fcaea6a934434e0460da (diff)
* 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
Diffstat (limited to 'lib')
-rw-r--r--lib/benchmark.rb157
1 files changed, 70 insertions, 87 deletions
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 <tt>Benchmark::Report</tt> object, which
# may be used to collect and report on the results of individual
# benchmark tests. Reserves <i>label_width</i> 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
# <tt>Benchmark::Tms</tt> 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
# <tt>%r</tt>:: Replaced by the elapsed real time, as reported by Tms#real
# <tt>%n</tt>:: 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}
]