module Benchmark

def benchmark(caption = "", label_width = nil, format = nil, *labels) # :yield: report

:yield: report
def benchmark(caption = "", label_width = nil, format = nil, *labels) # :yield: report
  sync = $stdout.sync
  $stdout.sync = true
  label_width ||= 0
  label_width += 1
  format ||= FORMAT
  report = Report.new(label_width, format)
  results = yield(report)
  print " " * report.width + caption unless caption.empty?
  report.list.each { |i|
    print i.label.to_s.ljust(report.width)
    print i.format(report.format, *format)
  }
  Array === results and results.grep(Tms).each {|t|
    print((labels.shift || t.label || "").ljust(label_width), t.format(format))
  }
  report.list
ensure
  $stdout.sync = sync unless sync.nil?
end

def bm(label_width = 0, *labels, &blk) # :yield: report

:yield: report
def bm(label_width = 0, *labels, &blk) # :yield: report
  benchmark(CAPTION, label_width, FORMAT, *labels, &blk)
end

def bmbm(width = 0) # :yield: job

:yield: job

Benchmark::Tms objects.
#bmbm yields a Benchmark::Job object and returns an array of

sort 1.450000 0.000000 1.450000 ( 1.455963)
sort! 1.460000 0.000000 1.460000 ( 1.458065)
user system total real

-------------------------------- total: 2.890000sec
sort 1.440000 0.000000 1.440000 ( 1.448257)
sort! 1.440000 0.010000 1.450000 ( 1.446833)
Rehearsal -----------------------------------------

Generates:

end
x.report("sort") { array.dup.sort }
x.report("sort!") { array.dup.sort! }
Benchmark.bmbm do |x|

array = (1..1000000).map { rand }

require 'benchmark'

calculate the required label width.
Because #bmbm takes two passes through the tests, it can

collection and other effects.
do, and the results are not guaranteed to be isolated from garbage
timings. In reality, though, there's only so much that #bmbm can
the real timings; the cost of this is not included in the
real. GC.start is executed before the start of each of
runtime environment stable, the second time for
the tests twice, the first time as a rehearsal in order to get the
that run later. #bmbm attempts to minimize this effect by running
earlier encounters different garbage collection overheads than
Sometimes benchmark results are skewed because code executed
def bmbm(width = 0) # :yield: job
  job = Job.new(width)
  yield(job)
  width = job.width + 1
  sync = $stdout.sync
  $stdout.sync = true
  # rehearsal
  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
  job.list.map { |label,item|
    GC.start
    print label.ljust(width)
    Benchmark.measure(label, &item).tap { |res| print res }
  }
ensure
  $stdout.sync = sync unless sync.nil?
end

def measure(label = "") # :yield:

:yield:

0.220000 0.000000 0.220000 ( 0.227313)

Generates:

puts time
end
n.times { a = "1" }
time = Benchmark.measure do

n = 1000000

require 'benchmark'

Benchmark::Tms object. Takes +label+ option.
Returns the time used to execute the given block as a
def measure(label = "") # :yield:
  t0, r0 = Process.times, Process.clock_gettime(Process::CLOCK_MONOTONIC)
  yield
  t1, r1 = Process.times, Process.clock_gettime(Process::CLOCK_MONOTONIC)
  Benchmark::Tms.new(t1.utime  - t0.utime,
                     t1.stime  - t0.stime,
                     t1.cutime - t0.cutime,
                     t1.cstime - t0.cstime,
                     r1 - r0,
                     label)
end

def realtime # :yield:

:yield:

#=> 0.5098029999935534
Benchmark.realtime { "a" * 1_000_000_000 }

The unit of time is seconds.
Returns the elapsed real time used to execute the given block.
def realtime # :yield:
  r0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  yield
  Process.clock_gettime(Process::CLOCK_MONOTONIC) - r0
end