mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
6b06ba0c05
commit
979ec8df5d
3 changed files with 264 additions and 93 deletions
32
ChangeLog
32
ChangeLog
|
@ -1,3 +1,35 @@
|
||||||
|
Tue Feb 1 00:10:30 2011 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
|
* 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
|
||||||
|
|
||||||
Mon Jan 31 23:27:23 2011 CHIKANAGA Tomoyuki <nagachika00@gmail.com>
|
Mon Jan 31 23:27:23 2011 CHIKANAGA Tomoyuki <nagachika00@gmail.com>
|
||||||
|
|
||||||
* node.c (add_id): remove duplicated rb_id2str() call.
|
* node.c (add_id): remove duplicated rb_id2str() call.
|
||||||
|
|
157
lib/benchmark.rb
157
lib/benchmark.rb
|
@ -103,10 +103,10 @@
|
||||||
# using the #benchmark method:
|
# using the #benchmark method:
|
||||||
#
|
#
|
||||||
# require 'benchmark'
|
# require 'benchmark'
|
||||||
# include Benchmark # we need the CAPTION and FMTSTR constants
|
# include Benchmark # we need the CAPTION and FORMAT constants
|
||||||
#
|
#
|
||||||
# n = 50000
|
# 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 }
|
# tf = x.report("for:") { for i in 1..n; a = "1"; end }
|
||||||
# tt = x.report("times:") { n.times do ; a = "1"; end }
|
# tt = x.report("times:") { n.times do ; a = "1"; end }
|
||||||
# tu = x.report("upto:") { 1.upto(n) 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"
|
BENCHMARK_VERSION = "2002-04-25" #:nodoc"
|
||||||
|
|
||||||
def Benchmark::times() # :nodoc:
|
|
||||||
Process::times()
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# Invokes the block with a <tt>Benchmark::Report</tt> object, which
|
# Invokes the block with a <tt>Benchmark::Report</tt> object, which
|
||||||
# may be used to collect and report on the results of individual
|
# may be used to collect and report on the results of individual
|
||||||
# benchmark tests. Reserves <i>label_width</i> leading spaces for
|
# benchmark tests. Reserves <i>label_width</i> leading spaces for
|
||||||
# labels on each line. Prints _caption_ at the top of the
|
# 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
|
# If the block returns an array of
|
||||||
# <tt>Benchmark::Tms</tt> objects, these will be used to format
|
# <tt>Benchmark::Tms</tt> objects, these will be used to format
|
||||||
# additional lines of output. If _label_ parameters are
|
# additional lines of output. If _label_ parameters are
|
||||||
|
@ -148,10 +145,10 @@ module Benchmark
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# require 'benchmark'
|
# require 'benchmark'
|
||||||
# include Benchmark # we need the CAPTION and FMTSTR constants
|
# include Benchmark # we need the CAPTION and FORMAT constants
|
||||||
#
|
#
|
||||||
# n = 50000
|
# 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 }
|
# tf = x.report("for:") { for i in 1..n; a = "1"; end }
|
||||||
# tt = x.report("times:") { n.times do ; a = "1"; end }
|
# tt = x.report("times:") { n.times do ; a = "1"; end }
|
||||||
# tu = x.report("upto:") { 1.upto(n) 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)
|
# >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
|
sync = STDOUT.sync
|
||||||
STDOUT.sync = true
|
STDOUT.sync = true
|
||||||
label_width ||= 0
|
label_width ||= 0
|
||||||
fmtstr ||= FMTSTR
|
format ||= FORMAT
|
||||||
raise ArgumentError, "no block" unless iterator?
|
print ' '*label_width + caption
|
||||||
print caption
|
report = Report.new(label_width, format)
|
||||||
results = yield(Report.new(label_width, fmtstr))
|
results = yield(report)
|
||||||
Array === results and results.grep(Tms).each {|t|
|
Array === results and results.grep(Tms).each {|t|
|
||||||
print((labels.shift || t.label || "").ljust(label_width),
|
print((labels.shift || t.label || "").ljust(label_width), t.format(format))
|
||||||
t.format(fmtstr))
|
|
||||||
}
|
}
|
||||||
STDOUT.sync = sync
|
STDOUT.sync = sync
|
||||||
|
report.list
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,7 +202,7 @@ module Benchmark
|
||||||
#
|
#
|
||||||
|
|
||||||
def bm(label_width = 0, *labels, &blk) # :yield: report
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -254,35 +251,24 @@ module Benchmark
|
||||||
STDOUT.sync = true
|
STDOUT.sync = true
|
||||||
|
|
||||||
# rehearsal
|
# rehearsal
|
||||||
print "Rehearsal "
|
puts 'Rehearsal '.ljust(width+CAPTION.length,'-')
|
||||||
puts '-'*(width+CAPTION.length - "Rehearsal ".length)
|
ets = job.list.inject(Tms.new) { |sum,(label,item)|
|
||||||
list = []
|
print label.ljust(width)
|
||||||
job.list.each{|label,item|
|
res = Benchmark.measure(&item)
|
||||||
print(label.ljust(width))
|
print res.format
|
||||||
res = Benchmark::measure(&item)
|
sum + res
|
||||||
print res.format()
|
}.format("total: %tsec")
|
||||||
list.push res
|
print " #{ets}\n\n".rjust(width+CAPTION.length+2,'-')
|
||||||
}
|
|
||||||
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)
|
|
||||||
|
|
||||||
# take
|
# take
|
||||||
print ' '*width, CAPTION
|
print ' '*width + CAPTION
|
||||||
list = []
|
job.list.map { |label,item|
|
||||||
ary = []
|
GC.start
|
||||||
job.list.each{|label,item|
|
|
||||||
GC::start
|
|
||||||
print label.ljust(width)
|
print label.ljust(width)
|
||||||
res = Benchmark::measure(&item)
|
Benchmark.measure(&item).tap { |res| print res.format }
|
||||||
print res.format()
|
}.tap {
|
||||||
ary.push res
|
STDOUT.sync = sync
|
||||||
list.push [label, res]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STDOUT.sync = sync
|
|
||||||
ary
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -290,9 +276,9 @@ module Benchmark
|
||||||
# Benchmark::Tms object.
|
# Benchmark::Tms object.
|
||||||
#
|
#
|
||||||
def measure(label = "") # :yield:
|
def measure(label = "") # :yield:
|
||||||
t0, r0 = Benchmark.times, Time.now
|
t0, r0 = Process.times, Time.now
|
||||||
yield
|
yield
|
||||||
t1, r1 = Benchmark.times, Time.now
|
t1, r1 = Process.times, Time.now
|
||||||
Benchmark::Tms.new(t1.utime - t0.utime,
|
Benchmark::Tms.new(t1.utime - t0.utime,
|
||||||
t1.stime - t0.stime,
|
t1.stime - t0.stime,
|
||||||
t1.cutime - t0.cutime,
|
t1.cutime - t0.cutime,
|
||||||
|
@ -307,11 +293,10 @@ module Benchmark
|
||||||
def realtime(&blk) # :yield:
|
def realtime(&blk) # :yield:
|
||||||
r0 = Time.now
|
r0 = Time.now
|
||||||
yield
|
yield
|
||||||
r1 = Time.now
|
Time.now - r0
|
||||||
r1.to_f - r0.to_f
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module_function :benchmark, :measure, :realtime, :bm, :bmbm
|
||||||
|
|
||||||
#
|
#
|
||||||
# A Job is a sequence of labelled blocks to be processed by the
|
# A Job is a sequence of labelled blocks to be processed by the
|
||||||
|
@ -335,10 +320,10 @@ module Benchmark
|
||||||
#
|
#
|
||||||
def item(label = "", &blk) # :yield:
|
def item(label = "", &blk) # :yield:
|
||||||
raise ArgumentError, "no block" unless block_given?
|
raise ArgumentError, "no block" unless block_given?
|
||||||
label += ' '
|
label = label.to_s
|
||||||
w = label.length
|
w = label.length
|
||||||
@width = w if @width < w
|
@width = w if @width < w
|
||||||
@list.push [label, blk]
|
@list << [label, blk]
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -347,14 +332,10 @@ module Benchmark
|
||||||
# An array of 2-element arrays, consisting of label and block pairs.
|
# An array of 2-element arrays, consisting of label and block pairs.
|
||||||
attr_reader :list
|
attr_reader :list
|
||||||
|
|
||||||
# Length of the widest label in the #list, plus one.
|
# Length of the widest label in the #list.
|
||||||
attr_reader :width
|
attr_reader :width
|
||||||
end
|
end
|
||||||
|
|
||||||
module_function :benchmark, :measure, :realtime, :bm, :bmbm
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# This class is used by the Benchmark.benchmark and Benchmark.bm methods.
|
# This class is used by the Benchmark.benchmark and Benchmark.bm methods.
|
||||||
# It is of little direct interest to the user.
|
# It is of little direct interest to the user.
|
||||||
|
@ -364,26 +345,29 @@ module Benchmark
|
||||||
# Returns an initialized Report instance.
|
# Returns an initialized Report instance.
|
||||||
# Usually, one doesn't call this method directly, as new
|
# Usually, one doesn't call this method directly, as new
|
||||||
# Report objects are created by the #benchmark and #bm methods.
|
# 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.
|
# format string used by Tms#format.
|
||||||
#
|
#
|
||||||
def initialize(width = 0, fmtstr = nil)
|
def initialize(width = 0, format = nil)
|
||||||
@width, @fmtstr = width, fmtstr
|
@width, @format, @list = width, format, []
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Prints the _label_ and measured time for the block,
|
# 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.
|
# formatting rules.
|
||||||
#
|
#
|
||||||
def item(label = "", *fmt, &blk) # :yield:
|
def item(label = "", *format, &blk) # :yield:
|
||||||
print label.ljust(@width)
|
print label.to_s.ljust(@width)
|
||||||
res = Benchmark::measure(&blk)
|
@list << res = Benchmark.measure(label, &blk)
|
||||||
print res.format(@fmtstr, *fmt)
|
print res.format(@format, *format)
|
||||||
res
|
res
|
||||||
end
|
end
|
||||||
|
|
||||||
alias report item
|
alias report item
|
||||||
|
|
||||||
|
# An array of Benchmark::Tms objects representing each item.
|
||||||
|
attr_reader :list
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -394,7 +378,7 @@ module Benchmark
|
||||||
#
|
#
|
||||||
class Tms
|
class Tms
|
||||||
CAPTION = " user system total real\n"
|
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
|
# User CPU time
|
||||||
attr_reader :utime
|
attr_reader :utime
|
||||||
|
@ -419,13 +403,12 @@ module Benchmark
|
||||||
|
|
||||||
#
|
#
|
||||||
# Returns an initialized Tms object which has
|
# Returns an initialized Tms object which has
|
||||||
# _u_ as the user CPU time, _s_ as the system CPU time,
|
# _utime_ as the user CPU time, _stime_ as the system CPU time,
|
||||||
# _cu_ as the children's user CPU time, _cs_ as the children's
|
# _cutime_ as the children's user CPU time, _cstime_ as the children's
|
||||||
# system CPU time, _real_ as the elapsed real time and _l_
|
# system CPU time, _real_ as the elapsed real time and _label_ as the label.
|
||||||
# as the label.
|
|
||||||
#
|
#
|
||||||
def initialize(u = 0.0, s = 0.0, cu = 0.0, cs = 0.0, real = 0.0, l = nil)
|
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 = u, s, cu, cs, real, l
|
@utime, @stime, @cutime, @cstime, @real, @label = utime, stime, cutime, cstime, real, label.to_s
|
||||||
@total = @utime + @stime + @cutime + @cstime
|
@total = @utime + @stime + @cutime + @cstime
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -434,14 +417,14 @@ module Benchmark
|
||||||
# Tms object, plus the time required to execute the code block (_blk_).
|
# Tms object, plus the time required to execute the code block (_blk_).
|
||||||
#
|
#
|
||||||
def add(&blk) # :yield:
|
def add(&blk) # :yield:
|
||||||
self + Benchmark::measure(&blk)
|
self + Benchmark.measure(&blk)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# An in-place version of #add.
|
# An in-place version of #add.
|
||||||
#
|
#
|
||||||
def add!(&blk)
|
def add!(&blk)
|
||||||
t = Benchmark::measure(&blk)
|
t = Benchmark.measure(&blk)
|
||||||
@utime = utime + t.utime
|
@utime = utime + t.utime
|
||||||
@stime = stime + t.stime
|
@stime = stime + t.stime
|
||||||
@cutime = cutime + t.cutime
|
@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>%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")
|
# <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.
|
# user, system and real elapsed time.
|
||||||
#
|
#
|
||||||
def format(arg0 = nil, *args)
|
def format(format = nil, *args)
|
||||||
fmtstr = (arg0 || FMTSTR).dup
|
str = (format || FORMAT).dup
|
||||||
fmtstr.gsub!(/(%[-+\.\d]*)n/){"#{$1}s" % label}
|
str.gsub!(/(%[-+\.\d]*)n/) { "#{$1}s" % label }
|
||||||
fmtstr.gsub!(/(%[-+\.\d]*)u/){"#{$1}f" % utime}
|
str.gsub!(/(%[-+\.\d]*)u/) { "#{$1}f" % utime }
|
||||||
fmtstr.gsub!(/(%[-+\.\d]*)y/){"#{$1}f" % stime}
|
str.gsub!(/(%[-+\.\d]*)y/) { "#{$1}f" % stime }
|
||||||
fmtstr.gsub!(/(%[-+\.\d]*)U/){"#{$1}f" % cutime}
|
str.gsub!(/(%[-+\.\d]*)U/) { "#{$1}f" % cutime }
|
||||||
fmtstr.gsub!(/(%[-+\.\d]*)Y/){"#{$1}f" % cstime}
|
str.gsub!(/(%[-+\.\d]*)Y/) { "#{$1}f" % cstime }
|
||||||
fmtstr.gsub!(/(%[-+\.\d]*)t/){"#{$1}f" % total}
|
str.gsub!(/(%[-+\.\d]*)t/) { "#{$1}f" % total }
|
||||||
fmtstr.gsub!(/(%[-+\.\d]*)r/){"(#{$1}f)" % real}
|
str.gsub!(/(%[-+\.\d]*)r/) { "(#{$1}f)" % real }
|
||||||
arg0 ? Kernel::format(fmtstr, *args) : fmtstr
|
format ? str % args : str
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -549,7 +532,7 @@ module Benchmark
|
||||||
CAPTION = Benchmark::Tms::CAPTION
|
CAPTION = Benchmark::Tms::CAPTION
|
||||||
|
|
||||||
# The default format string used to display times. See also Benchmark::Tms#format.
|
# The default format string used to display times. See also Benchmark::Tms#format.
|
||||||
FMTSTR = Benchmark::Tms::FMTSTR
|
FORMAT = Benchmark::Tms::FORMAT
|
||||||
end
|
end
|
||||||
|
|
||||||
if __FILE__ == $0
|
if __FILE__ == $0
|
||||||
|
@ -557,15 +540,15 @@ if __FILE__ == $0
|
||||||
|
|
||||||
n = ARGV[0].to_i.nonzero? || 50000
|
n = ARGV[0].to_i.nonzero? || 50000
|
||||||
puts %Q([#{n} times iterations of `a = "1"'])
|
puts %Q([#{n} times iterations of `a = "1"'])
|
||||||
benchmark(" " + CAPTION, 7, FMTSTR) do |x|
|
benchmark(" " + CAPTION, 7, FORMAT) do |x|
|
||||||
x.report("for:") {for _ in 1..n; _ = "1"; end} # Benchmark::measure
|
x.report("for:") {for _ in 1..n; _ = "1"; end} # Benchmark.measure
|
||||||
x.report("times:") {n.times do ; _ = "1"; end}
|
x.report("times:") {n.times do ; _ = "1"; end}
|
||||||
x.report("upto:") {1.upto(n) do ; _ = "1"; end}
|
x.report("upto:") {1.upto(n) do ; _ = "1"; end}
|
||||||
end
|
end
|
||||||
|
|
||||||
benchmark do
|
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{n.times do ; _ = "1"; end},
|
||||||
measure{1.upto(n) do ; _ = "1"; end}
|
measure{1.upto(n) do ; _ = "1"; end}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,10 +1,166 @@
|
||||||
require "test/unit"
|
require 'minitest/spec'
|
||||||
require "benchmark"
|
require 'benchmark'
|
||||||
|
|
||||||
class TestBenchmark < Test::Unit::TestCase
|
MiniTest::Unit.autorun
|
||||||
def test_add!
|
|
||||||
assert_nothing_raised("[ruby-dev:40906]") do
|
describe Benchmark do
|
||||||
Benchmark::Tms.new.add! {}
|
BENCH_FOR_TIMES_UPTO = lambda do |x|
|
||||||
|
n = 1000
|
||||||
|
tf = x.report("for:") { for _ in 1..n; '1'; end }
|
||||||
|
tt = x.report("times:") { n.times do ; '1'; end }
|
||||||
|
tu = x.report("upto:") { 1.upto(n) do ; '1'; end }
|
||||||
|
[tf+tt+tu, (tf+tt+tu)/3]
|
||||||
|
end
|
||||||
|
|
||||||
|
BENCH_FOR_TIMES_UPTO_NO_LABEL = lambda do |x|
|
||||||
|
n = 1000
|
||||||
|
x.report { for _ in 1..n; '1'; end }
|
||||||
|
x.report { n.times do ; '1'; end }
|
||||||
|
x.report { 1.upto(n) do ; '1'; end }
|
||||||
|
end
|
||||||
|
|
||||||
|
def labels
|
||||||
|
%w[first second third]
|
||||||
|
end
|
||||||
|
|
||||||
|
def bench(type = :bm, *args, &block)
|
||||||
|
if block
|
||||||
|
Benchmark.send(type, *args, &block)
|
||||||
|
else
|
||||||
|
Benchmark.send(type, *args) do |x|
|
||||||
|
labels.each { |label|
|
||||||
|
x.report(label) {}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def capture_output
|
||||||
|
capture_io { yield }.first.gsub(/\d\.\d{6}/, '--time--')
|
||||||
|
end
|
||||||
|
|
||||||
|
def capture_bench_output(type, *args, &block)
|
||||||
|
capture_output { bench(type, *args, &block) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'Tms' do
|
||||||
|
it 'outputs nicely' do
|
||||||
|
Benchmark::Tms.new.to_s.must_equal " 0.000000 0.000000 0.000000 ( 0.000000)\n"
|
||||||
|
Benchmark::Tms.new(1,2,3,4,5).to_s.must_equal " 1.000000 2.000000 10.000000 ( 5.000000)\n"
|
||||||
|
Benchmark::Tms.new(1,2,3,4,5,'label').format('%u %y %U %Y %t %r %n').must_equal \
|
||||||
|
"1.000000 2.000000 3.000000 4.000000 10.000000 (5.000000) label"
|
||||||
|
Benchmark::Tms.new(1).format('%u %.3f', 2).must_equal "1.000000 2.000"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'wont modify the format String given' do
|
||||||
|
format = "format %u"
|
||||||
|
Benchmark::Tms.new.format(format)
|
||||||
|
format.must_equal "format %u"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'benchmark' do
|
||||||
|
it 'makes extra calcultations with an Array at the end of the benchmark and show the result' do
|
||||||
|
capture_bench_output(:benchmark,
|
||||||
|
Benchmark::CAPTION, 7,
|
||||||
|
Benchmark::FORMAT, ">total:", ">avg:",
|
||||||
|
&BENCH_FOR_TIMES_UPTO).must_equal BENCHMARK_OUTPUT_WITH_TOTAL_AVG
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'bm' do
|
||||||
|
it "returns an Array of the times with the labels" do
|
||||||
|
capture_io do
|
||||||
|
results = bench
|
||||||
|
results.must_be_instance_of Array
|
||||||
|
results.size.must_equal labels.size
|
||||||
|
results.zip(labels).each { |tms, label|
|
||||||
|
tms.must_be_instance_of Benchmark::Tms
|
||||||
|
tms.label.must_equal label
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'correctly guess the label width even when not given' do
|
||||||
|
skip :not_implemented
|
||||||
|
capture_bench_output(:bm).must_equal BM_OUTPUT
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'correctly output when the label width is given' do
|
||||||
|
capture_bench_output(:bm, 6).must_equal BM_OUTPUT
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'correctly output when no label is given' do
|
||||||
|
capture_bench_output(:bm, &BENCH_FOR_TIMES_UPTO_NO_LABEL).must_equal BM_OUTPUT_NO_LABEL
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can make extra calcultations with an array at the end of the benchmark' do
|
||||||
|
capture_bench_output(:bm, 7, ">total:", ">avg:",
|
||||||
|
&BENCH_FOR_TIMES_UPTO).must_equal BENCHMARK_OUTPUT_WITH_TOTAL_AVG
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'bmbm' do
|
||||||
|
it 'correctly guess the label width even when not given' do
|
||||||
|
capture_bench_output(:bmbm).must_equal BMBM_OUTPUT
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'correctly output when the label width is given (bmbm ignore it, but it is a frequent mistake)' do
|
||||||
|
capture_bench_output(:bmbm, 6).must_equal BMBM_OUTPUT
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'Report' do
|
||||||
|
describe '#item' do
|
||||||
|
it 'shows the title, even if not a string' do
|
||||||
|
capture_bench_output(:bm) { |x| x.report(:title) {} }.must_include 'title'
|
||||||
|
capture_bench_output(:bmbm) { |x| x.report(:title) {} }.must_include 'title'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'Bugs' do
|
||||||
|
it '[ruby-dev:40906] can add in-place the time of execution of the block given' do
|
||||||
|
t = Benchmark::Tms.new
|
||||||
|
t.real.must_equal 0
|
||||||
|
t.add! {}
|
||||||
|
t.real.wont_equal 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
BM_OUTPUT = <<BENCH
|
||||||
|
user system total real
|
||||||
|
first --time-- --time-- --time-- ( --time--)
|
||||||
|
second --time-- --time-- --time-- ( --time--)
|
||||||
|
third --time-- --time-- --time-- ( --time--)
|
||||||
|
BENCH
|
||||||
|
|
||||||
|
BM_OUTPUT_NO_LABEL = <<BENCH
|
||||||
|
user system total real
|
||||||
|
--time-- --time-- --time-- ( --time--)
|
||||||
|
--time-- --time-- --time-- ( --time--)
|
||||||
|
--time-- --time-- --time-- ( --time--)
|
||||||
|
BENCH
|
||||||
|
|
||||||
|
BMBM_OUTPUT = <<BENCH
|
||||||
|
Rehearsal -----------------------------------------
|
||||||
|
first --time-- --time-- --time-- ( --time--)
|
||||||
|
second --time-- --time-- --time-- ( --time--)
|
||||||
|
third --time-- --time-- --time-- ( --time--)
|
||||||
|
-------------------------------- total: --time--sec
|
||||||
|
|
||||||
|
user system total real
|
||||||
|
first --time-- --time-- --time-- ( --time--)
|
||||||
|
second --time-- --time-- --time-- ( --time--)
|
||||||
|
third --time-- --time-- --time-- ( --time--)
|
||||||
|
BENCH
|
||||||
|
|
||||||
|
BENCHMARK_OUTPUT_WITH_TOTAL_AVG = <<BENCH
|
||||||
|
user system total real
|
||||||
|
for: --time-- --time-- --time-- ( --time--)
|
||||||
|
times: --time-- --time-- --time-- ( --time--)
|
||||||
|
upto: --time-- --time-- --time-- ( --time--)
|
||||||
|
>total: --time-- --time-- --time-- ( --time--)
|
||||||
|
>avg: --time-- --time-- --time-- ( --time--)
|
||||||
|
BENCH
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue