* lib/benchmark.rb: merge eregon/benchmark.

https://github.com/eregon/ruby/tree/benchmark
  patched by Benoit Daloze. [ruby-core:37593] [Bug #4940]

* lib/benchmark (Benchmark#bmbm): bmbm should be consistent with bm
  for the return value.

* test/benchmark: remove preemptive test instead of skipping
  I removed the preemptive test I wrote for Feature #4197.
  I'll add it back when the implementation will be able to satisfy it.

* lib/benchmark (Benchmark#bmbm): remove useless explicit call,
  #format is an alias of #to_s test/benchmark: add a test for
  format of long time.

* lib/benchmark: fix label width: always add 1 to ensure there is a
  space delimiter even with times over 100s
  When I asked for Feature #4197, I wanted to make delimiting spaces
  consistent for #bm and #bmbm.
  But with times over 100s, the output contains no space between the
  label and the first time (user).
  Now both ensure there is always a space, even if that means 3 spaces
  with times under 10s (because it is formatted as %10.6f)

* test/benchmark: let labels be a constant
  lib/benchmark (Benchmark#realtime): avoid creating an unused Proc
  lib/benchmark (Benchmark#benchmark): use ensure clause to restore
  STDOUT.sync, as in #bmbm

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32269 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
naruse 2011-06-28 06:09:46 +00:00
parent 565336acca
commit 4870feb31a
3 changed files with 74 additions and 44 deletions

View File

@ -1,3 +1,34 @@
Tue Jun 28 15:09:21 2011 NARUSE, Yui <naruse@ruby-lang.org>
* lib/benchmark.rb: merge eregon/benchmark.
https://github.com/eregon/ruby/tree/benchmark
patched by Benoit Daloze. [ruby-core:37593] [Bug #4940]
* lib/benchmark (Benchmark#bmbm): bmbm should be consistent with bm
for the return value.
* test/benchmark: remove preemptive test instead of skipping
I removed the preemptive test I wrote for Feature #4197.
I'll add it back when the implementation will be able to satisfy it.
* lib/benchmark (Benchmark#bmbm): remove useless explicit call,
#format is an alias of #to_s test/benchmark: add a test for
format of long time.
* lib/benchmark: fix label width: always add 1 to ensure there is a
space delimiter even with times over 100s
When I asked for Feature #4197, I wanted to make delimiting spaces
consistent for #bm and #bmbm.
But with times over 100s, the output contains no space between the
label and the first time (user).
Now both ensure there is always a space, even if that means 3 spaces
with times under 10s (because it is formatted as %10.6f)
* test/benchmark: let labels be a constant
lib/benchmark (Benchmark#realtime): avoid creating an unused Proc
lib/benchmark (Benchmark#benchmark): use ensure clause to restore
STDOUT.sync, as in #bmbm
Tue Jun 28 13:41:51 2011 NAKAMURA Usaku <usa@ruby-lang.org> Tue Jun 28 13:41:51 2011 NAKAMURA Usaku <usa@ruby-lang.org>
* thread_win32.c (native_stop_timer_thread): fixed commit miss of * thread_win32.c (native_stop_timer_thread): fixed commit miss of

View File

@ -167,6 +167,7 @@ module Benchmark
sync = STDOUT.sync sync = STDOUT.sync
STDOUT.sync = true STDOUT.sync = true
label_width ||= 0 label_width ||= 0
label_width += 1
format ||= FORMAT format ||= FORMAT
print ' '*label_width + caption print ' '*label_width + caption
report = Report.new(label_width, format) report = Report.new(label_width, format)
@ -174,8 +175,9 @@ module Benchmark
Array === results and results.grep(Tms).each {|t| Array === results and results.grep(Tms).each {|t|
print((labels.shift || t.label || "").ljust(label_width), t.format(format)) print((labels.shift || t.label || "").ljust(label_width), t.format(format))
} }
STDOUT.sync = sync
report.list report.list
ensure
STDOUT.sync = sync unless sync.nil?
end end
@ -244,7 +246,7 @@ module Benchmark
def bmbm(width = 0, &blk) # :yield: job def bmbm(width = 0, &blk) # :yield: job
job = Job.new(width) job = Job.new(width)
yield(job) yield(job)
width = job.width width = job.width + 1
sync = STDOUT.sync sync = STDOUT.sync
STDOUT.sync = true STDOUT.sync = true
@ -263,7 +265,7 @@ module Benchmark
job.list.map { |label,item| job.list.map { |label,item|
GC.start GC.start
print label.ljust(width) print label.ljust(width)
Benchmark.measure(&item).tap { |res| print res.format } Benchmark.measure(label, &item).tap { |res| print res }
} }
ensure ensure
STDOUT.sync = sync unless sync.nil? STDOUT.sync = sync unless sync.nil?
@ -288,7 +290,7 @@ module Benchmark
# #
# Returns the elapsed real time used to execute the given block. # Returns the elapsed real time used to execute the given block.
# #
def realtime(&blk) # :yield: def realtime # :yield:
r0 = Time.now r0 = Time.now
yield yield
Time.now - r0 Time.now - r0

View File

@ -19,16 +19,14 @@ describe Benchmark do
x.report { 1.upto(n) do ; '1'; end } x.report { 1.upto(n) do ; '1'; end }
end end
def labels LABELS = %w[first second third]
%w[first second third]
end
def bench(type = :bm, *args, &block) def bench(type = :bm, *args, &block)
if block if block
Benchmark.send(type, *args, &block) Benchmark.send(type, *args, &block)
else else
Benchmark.send(type, *args) do |x| Benchmark.send(type, *args) do |x|
labels.each { |label| LABELS.each { |label|
x.report(label) {} x.report(label) {}
} }
end end
@ -50,6 +48,8 @@ describe Benchmark do
Benchmark::Tms.new(1,2,3,4,5,'label').format('%u %y %U %Y %t %r %n').must_equal \ 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" "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" Benchmark::Tms.new(1).format('%u %.3f', 2).must_equal "1.000000 2.000"
Benchmark::Tms.new(100, 150, 0, 0, 200).to_s.must_equal \
"100.000000 150.000000 250.000000 (200.000000)\n"
end end
it 'wont modify the format String given' do it 'wont modify the format String given' do
@ -70,20 +70,17 @@ describe Benchmark do
describe 'bm' do describe 'bm' do
it "returns an Array of the times with the labels" do it "returns an Array of the times with the labels" do
[:bm, :bmbm].each do |meth|
capture_io do capture_io do
results = bench results = bench(meth)
results.must_be_instance_of Array results.must_be_instance_of Array
results.size.must_equal labels.size results.size.must_equal LABELS.size
results.zip(labels).each { |tms, label| results.zip(LABELS).each { |tms, label|
tms.must_be_instance_of Benchmark::Tms tms.must_be_instance_of Benchmark::Tms
tms.label.must_equal label tms.label.must_equal label
} }
end end
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 end
it 'correctly output when the label width is given' do it 'correctly output when the label width is given' do
@ -144,11 +141,11 @@ BM_OUTPUT_NO_LABEL = <<BENCH
BENCH BENCH
BMBM_OUTPUT = <<BENCH BMBM_OUTPUT = <<BENCH
Rehearsal ----------------------------------------- Rehearsal ------------------------------------------
first --time-- --time-- --time-- ( --time--) first --time-- --time-- --time-- ( --time--)
second --time-- --time-- --time-- ( --time--) second --time-- --time-- --time-- ( --time--)
third --time-- --time-- --time-- ( --time--) third --time-- --time-- --time-- ( --time--)
-------------------------------- total: --time--sec --------------------------------- total: --time--sec
user system total real user system total real
first --time-- --time-- --time-- ( --time--) first --time-- --time-- --time-- ( --time--)