1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Services to gather information on the performance of events by categories
17 # Provides `PerfMap` to manage all the categories and
18 # `PerfEntry` for per-category statistics.
21 # for i in 100.times do
22 # var clock = new Clock
24 # # Do some "work" here
25 # nanosleep(0, 1000000)
28 # sys.perfs["sleep 1ms"].add clock.lapse
30 # # Do some other "work" here
31 # nanosleep(0, 5000000)
34 # sys.perfs["sleep 5ms"].add clock.lapse
37 # assert sys.perfs["sleep 1ms"].count == 100
38 # assert sys.perfs["sleep 1ms"].avg.is_approx(0.001, 0.001)
39 # assert sys.perfs["sleep 5ms"].avg.is_approx(0.005, 0.005)
41 module performance_analysis
46 # Main `PerfMap` available by default
47 var perfs
= new PerfMap
50 # Collection of statistics on many events
52 super HashMap[String, PerfEntry]
54 redef fun provide_default_value
(key
)
56 if not key
isa String then return super
58 var ts
= new PerfEntry(key
)
63 # Number of digits to the right of the decimal points in reports created by `to_s`
66 var precision
= 4 is writable
72 var table
= new Map[String, Array[String]]
73 for event
, stats
in self do
74 table
[event
] = [event
,
75 stats
.min
.to_precision
(prec
),
76 stats
.max
.to_precision
(prec
),
77 stats
.avg
.to_precision
(prec
),
78 stats
.sum
.to_precision
(prec
),
83 for event
, row
in table
do
84 for i
in row
.length
.times
do
85 widths
[i
] = widths
[i
].max
(row
[i
].length
)
89 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"
91 var sorted_events
= table
.keys
.to_a
92 alpha_comparator
.sort sorted_events
93 for event
in sorted_events
do
94 var row
= table
[event
]
96 for c
in row
.length
.times
do
100 s
+= cell
.justify
(widths
[c
], 0.0, '.')
101 else s
+= cell
.justify
(widths
[c
], 1.0)
109 # Statistics on wall clock execution time of a category of events by `name`
112 # Name of the category
115 # Shortest execution time of registered events
118 # Longest execution time of registered events
121 # Average execution time of registered events
124 # Number of registered events
127 # Total execution time of this event
130 # Register a new event execution time in seconds
133 if time
.to_f
< min
.to_f
or count
== 0 then min
= time
134 if time
.to_f
> max
.to_f
then max
= time
138 avg
= sum
/ count
.to_f
141 redef fun to_s
do return "min {min}, max {max}, avg {avg}, sum {sum}, count {count}"