127 lines
3.8 KiB
Ruby
Executable File
127 lines
3.8 KiB
Ruby
Executable File
#
|
|
# File:: RSNProfiler.rb
|
|
# Description:: A simpler profiler.
|
|
# Author:: Derek Ward <derek.ward@rockstarnorth.com>
|
|
# Date:: 14 April 2009
|
|
#
|
|
|
|
#----------------------------------------------------------------------------
|
|
# Uses
|
|
#----------------------------------------------------------------------------
|
|
# None
|
|
|
|
#----------------------------------------------------------------------------
|
|
# Implementation
|
|
#----------------------------------------------------------------------------
|
|
module Pipeline
|
|
module Util
|
|
|
|
# == Description
|
|
# a simple timer/profiler class for profiling performance
|
|
# eg.
|
|
#
|
|
# myTimer = RSNProfiler.new("mytimername")
|
|
# func()
|
|
# myTimer.end
|
|
#
|
|
# OR ( with multiple samples counted )
|
|
#
|
|
# myTimer = RSNProfiler.new("mytimername",false)
|
|
# 10.times do
|
|
# myTimer.start
|
|
# func()
|
|
# myTimer.stop
|
|
# end
|
|
# myTimer.end
|
|
|
|
class RSNProfiler
|
|
@@verbose = true # puts the results?
|
|
@@display_detail = true # detailed profile info?
|
|
@@display_in_minutes = true # allows you to disable the higher order display units, useful for comparitive display
|
|
@@display_in_seconds = true # allows you to disable the higher order display units, useful for comparitive display
|
|
@@precision = "%0.4f" # fractional precision formatting string
|
|
|
|
# == Description
|
|
# create the timer, and possibly start it running.
|
|
def initialize( name = "RSNProfiler", startup = true )
|
|
@name = name
|
|
@elapsed = 0.0
|
|
@samples = 0
|
|
#Kernel.sleep(0.1) # 'supposedly' this might be required to address the update frequency of the Time class , but didn't work?
|
|
start() if startup
|
|
end
|
|
|
|
# == Description
|
|
# end the timer and optionally display it
|
|
def end( display = true )
|
|
stop( display )
|
|
end
|
|
|
|
# == Description
|
|
# start the timer
|
|
def start()
|
|
@samples += 1
|
|
@start = timestamp()
|
|
end
|
|
|
|
# == Description
|
|
# stop/pause the timer and optionally display it
|
|
def stop( display = false )
|
|
@end = timestamp()
|
|
@elapsed += last_duration
|
|
throw RuntimeError.new("End and Start times suspect : Start #{@start} End #{@end} Elapsed #{@elapsed}") if @elapsed < 0
|
|
puts to_s if ( @@verbose and display )
|
|
end
|
|
|
|
def last_duration
|
|
@end-@start
|
|
end
|
|
|
|
def to_s()
|
|
@@display_detail ? to_s_detailed : to_s_simple
|
|
end
|
|
|
|
def to_s_detailed()
|
|
"#{@name.to_s.ljust(25)} : (samples=#{@samples.to_s.rjust(8)}) : (mean=#{(@@precision % mean_milliseconds()).to_s.rjust(15)}ms) : (elapsed=#{elapsed_string.rjust(20)})"
|
|
end
|
|
|
|
def to_s_simple()
|
|
"#{@name.to_s.ljust(25)} : (elapsed=#{elapsed_string.rjust(20)})"
|
|
end
|
|
|
|
def mean_milliseconds()
|
|
elapsed_milliseconds/@samples
|
|
end
|
|
|
|
def elapsed_minutes()
|
|
@elapsed / 60.0
|
|
end
|
|
|
|
def elapsed_seconds()
|
|
@elapsed
|
|
end
|
|
|
|
def elapsed_milliseconds()
|
|
@elapsed * 1000.0
|
|
end
|
|
|
|
private
|
|
def elapsed_string()
|
|
return "#{(@@precision % elapsed_minutes).to_s.rjust(20)} mins" if elapsed_minutes > 1.0 and @@display_in_minutes
|
|
return "#{(@@precision % elapsed_seconds).to_s.rjust(20)} secs" if elapsed_seconds > 1.0 and @@display_in_seconds
|
|
return "#{(@@precision % elapsed_milliseconds).to_s.rjust(20)} ms"
|
|
end
|
|
|
|
# == Description
|
|
# Return the time in micro seconds
|
|
def timestamp()
|
|
#timestamp = Time.now.floor + (Time.now.usec/1000000.0)
|
|
#puts "timestamp : #{timestamp}"
|
|
# DW - it looks suspect but sometimes the timestamp look very similar from call to call
|
|
# however it seems to have worked in a test I've done.... to be tested a bit better when I get time.
|
|
Time.now.to_f
|
|
end
|
|
end # class RSNProfiler
|
|
end # module util
|
|
end # module pipeline
|