# This file is part of NIT (http://www.nitlanguage.org). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # 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 redef fun to_s do return "* " + join("\n* ", ": ") 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 with a `Timespec` fun add(lapse: Timespec) do add_float lapse.to_f # Register a new event execution time in seconds using a `Float` fun add_float(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