Provides PerfMap
to manage all the categories and
PerfEntry
for per-category statistics.
for i in 100.times do
var clock = new Clock
# Do some "work" here
nanosleep(0, 1000000)
# Register the perf
sys.perfs["sleep 1ms"].add clock.lapse
# Do some other "work" here
nanosleep(0, 5000000)
# Register the perf
sys.perfs["sleep 5ms"].add clock.lapse
end
assert sys.perfs["sleep 1ms"].count == 100
assert sys.perfs["sleep 1ms"].avg.is_approx(0.001, 0.001)
assert sys.perfs["sleep 5ms"].avg.is_approx(0.005, 0.005)
performance_analysis :: PerfEntry
Statistics on wall clock execution time of a category of events byname
performance_analysis $ PerfEntry
Statistics on wall clock execution time of a category of events byname
core :: union_find
union–find algorithm using an efficient disjoint-set data structureEulerCamera
and App::frame_core_draw
to get a stereoscopic view
# Services to gather information on the performance of events by categories
#
# Provides `PerfMap` to manage all the categories and
# `PerfEntry` for per-category statistics.
#
# ~~~
# for i in 100.times do
# var clock = new Clock
#
# # Do some "work" here
# nanosleep(0, 1000000)
#
# # Register the perf
# sys.perfs["sleep 1ms"].add clock.lapse
#
# # Do some other "work" here
# nanosleep(0, 5000000)
#
# # Register the perf
# sys.perfs["sleep 5ms"].add clock.lapse
# end
#
# assert sys.perfs["sleep 1ms"].count == 100
# assert sys.perfs["sleep 1ms"].avg.is_approx(0.001, 0.001)
# assert sys.perfs["sleep 5ms"].avg.is_approx(0.005, 0.005)
# ~~~
module performance_analysis
import realtime
redef class Sys
# Main `PerfMap` available by default
var perfs = new PerfMap
end
# Collection of statistics on many events
class PerfMap
super HashMap[String, PerfEntry]
redef fun provide_default_value(key)
do
if not key isa String then return super
var ts = new PerfEntry(key)
self[key] = ts
return ts
end
# Number of digits to the right of the decimal points in reports created by `to_s`
#
# Defaults to 4.
var precision = 4 is writable
redef fun to_s
do
var prec = precision
var table = new Map[String, Array[String]]
for event, stats in self do
table[event] = [event,
stats.min.to_precision(prec),
stats.max.to_precision(prec),
stats.avg.to_precision(prec),
stats.sum.to_precision(prec),
stats.count.to_s]
end
var widths = [0] * 6
for event, row in table do
for i in row.length.times do
widths[i] = widths[i].max(row[i].length)
end
end
var s = "# {"Event".justify(widths[0], 0.0)} {"min".justify(widths[1], 0.5)} {"max".justify(widths[2], 0.5)} {"avg".justify(widths[3], 0.5)} {"sum".justify(widths[4], 0.5)} {"count".justify(widths[5], 0.5)}\n"
var sorted_events = table.keys.to_a
alpha_comparator.sort sorted_events
for event in sorted_events do
var row = table[event]
s += "*"
for c in row.length.times do
var cell = row[c]
s += " "
if c == 0 then
s += cell.justify(widths[c], 0.0, '.')
else s += cell.justify(widths[c], 1.0)
end
s += "\n"
end
return s
end
end
# Statistics on wall clock execution time of a category of events by `name`
class PerfEntry
# Name of the category
var name: String
# Shortest execution time of registered events
var min = 0.0
# Longest execution time of registered events
var max = 0.0
# Average execution time of registered events
var avg = 0.0
# Number of registered events
var count = 0
# Total execution time of this event
var sum = 0.0
# Register a new event execution time in seconds
fun add(time: Float)
do
if time.to_f < min.to_f or count == 0 then min = time
if time.to_f > max.to_f then max = time
sum += time
count += 1
avg = sum / count.to_f
end
redef fun to_s do return "min {min}, max {max}, avg {avg}, sum {sum}, count {count}"
end
lib/performance_analysis/performance_analysis.nit:15,1--142,3