calog/vendor/mruby/mrbgems/mruby-benchmark/mrblib/benchmark.rb
2026-07-04 20:25:00 -05:00

131 lines
3.1 KiB
Ruby
Vendored

module Benchmark
# Timing measurement result
class Tms
attr_reader :utime, :stime, :cutime, :cstime, :real
attr_reader :objects, :memory
def initialize(utime, stime, cutime, cstime, real, label = nil, objects = nil, memory = nil)
@utime = utime
@stime = stime
@cutime = cutime
@cstime = cstime
@real = real
@label = label
@objects = objects
@memory = memory
end
def total
@utime + @stime + @cutime + @cstime
end
def to_s
"%10.6f %10.6f %10.6f (%10.6f)\n" % [@utime, @stime, total, @real]
end
def format(format_str)
str = format_str.dup
str.gsub!('%u', @utime.to_s)
str.gsub!('%s', @stime.to_s)
str.gsub!('%t', total.to_s)
str.gsub!('%r', @real.to_s)
str.gsub!('%o', @objects.to_s) if @objects
str.gsub!('%m', @memory.to_s) if @memory
str.gsub!('%n', @label.to_s) if @label
str
end
end
# Report class for formatted benchmark output
class Report
def initialize(width = 0)
@width = width
@results = []
end
def report(label = "")
tms = Benchmark.measure { yield }
# Create new Tms with label set
tms = Benchmark::Tms.new(tms.utime, tms.stime, tms.cutime, tms.cstime,
tms.real, label, tms.objects, tms.memory)
label_str = label.to_s
if label_str.length < @width
label_str = label_str + " " * (@width - label_str.length)
end
if $stdout
$stdout.print label_str
$stdout.print tms.to_s
end
@results << tms
tms
end
def results
@results
end
end
# Measure execution time of a block
def self.measure(memory: false)
start_time = Time.now
start_objects = nil
start_count = nil
if memory
if Object.const_defined?(:ObjectSpace)
start_count = ObjectSpace.count_objects
start_objects = start_count.values.inject(0) {|sum, n| sum + n }
end
end
yield
end_time = Time.now
real = end_time - start_time
objects_allocated = nil
memory_allocated = nil
if memory && start_count
end_count = ObjectSpace.count_objects
end_objects = end_count.values.inject(0) {|sum, n| sum + n }
objects_allocated = end_objects - start_objects
# Estimate memory based on object count
# Average object overhead in mruby (approximate)
memory_allocated = objects_allocated * 40
end
# mruby typically doesn't have per-process CPU time
# Set user/system times to 0
Tms.new(0.0, 0.0, 0.0, 0.0, real, nil, objects_allocated, memory_allocated)
end
# Return only real time as a float
def self.realtime
start_time = Time.now
yield
end_time = Time.now
end_time - start_time
end
# Formatted benchmark with labeled reports
def self.bm(label_width = 0)
report = Report.new(label_width)
# Print header
if $stdout
if label_width > 0
$stdout.print " " * label_width
end
$stdout.puts " user system total real"
end
yield report
report
end
end