* 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,22 +70,19 @@ 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
capture_io do [:bm, :bmbm].each do |meth|
results = bench capture_io do
results.must_be_instance_of Array results = bench(meth)
results.size.must_equal labels.size results.must_be_instance_of Array
results.zip(labels).each { |tms, label| results.size.must_equal LABELS.size
tms.must_be_instance_of Benchmark::Tms results.zip(LABELS).each { |tms, label|
tms.label.must_equal label tms.must_be_instance_of Benchmark::Tms
} tms.label.must_equal label
}
end
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
it 'correctly output when the label width is given' do it 'correctly output when the label width is given' do
capture_bench_output(:bm, 6).must_equal BM_OUTPUT capture_bench_output(:bm, 6).must_equal BM_OUTPUT
end end
@ -130,37 +127,37 @@ describe Benchmark do
end end
BM_OUTPUT = <<BENCH BM_OUTPUT = <<BENCH
user system total real user system total real
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--)
BENCH BENCH
BM_OUTPUT_NO_LABEL = <<BENCH BM_OUTPUT_NO_LABEL = <<BENCH
user system total real user system total real
--time-- --time-- --time-- ( --time--) --time-- --time-- --time-- ( --time--)
--time-- --time-- --time-- ( --time--) --time-- --time-- --time-- ( --time--)
--time-- --time-- --time-- ( --time--) --time-- --time-- --time-- ( --time--)
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--)
second --time-- --time-- --time-- ( --time--) second --time-- --time-- --time-- ( --time--)
third --time-- --time-- --time-- ( --time--) third --time-- --time-- --time-- ( --time--)
BENCH BENCH
BENCHMARK_OUTPUT_WITH_TOTAL_AVG = <<BENCH BENCHMARK_OUTPUT_WITH_TOTAL_AVG = <<BENCH
user system total real user system total real
for: --time-- --time-- --time-- ( --time--) for: --time-- --time-- --time-- ( --time--)
times: --time-- --time-- --time-- ( --time--) times: --time-- --time-- --time-- ( --time--)
upto: --time-- --time-- --time-- ( --time--) upto: --time-- --time-- --time-- ( --time--)
>total: --time-- --time-- --time-- ( --time--) >total: --time-- --time-- --time-- ( --time--)
>avg: --time-- --time-- --time-- ( --time--) >avg: --time-- --time-- --time-- ( --time--)
BENCH BENCH