2 Instrumentation Functions
4 Copyright (c) 2007 Brett Lajzer
6 See LICENSE for license information.
8 This is code to do instrumentation and profiling.
9 Call 'instr_begin' to start instrumentation, passing an identifier string
10 Call 'instr_end' to stop instrumentation, passing the same identifier
11 Call 'instr_track' where the first argument is an id and the second a value
12 to track the value of a variable across a number of arbitrary samples
13 'instr_stats' outputs gathered information to stdout.
21 --keep vars in a local environment for cleanliness
28 local temp_start
= get_ticks()
30 --starts instrumentation for an id
31 function instr_begin(id
)
32 --check to see that we're not trying to nest these calls
33 --and throw an error if we are
34 if temp_time
[id
] ~= nil then
35 error("ERROR: Attempt to nest instrumentations for same id: "..id
)
38 --increment call counter
39 if call_count
[id
] then
40 call_count
[id
] = call_count
[id
] + 1
45 --store current time in ms
46 temp_time
[id
] = get_ticks()
50 --end instrumentation for an id
51 function instr_end(id
)
52 --check to make sure we're ending a running instrumentation
53 -- throw an error if not.
54 if temp_time
[id
] == nil then
55 error("ERROR: Can't end instrumentation on id: "..id
..". Instrumentation not started.",2)
58 --add current time delta to total for id
60 run_time
[id
] = run_time
[id
] + (get_ticks() - temp_time
[id
])
62 run_time
[id
] = get_ticks() - temp_time
[id
]
65 --delete temp entry to enable error detection
70 --track the value of a variable
71 function instr_track(id
, val
)
72 if var_track
[id
] == nil then
75 local pos
= #var_track
[id
]+1
76 var_track
[id
][pos
] = val
80 --prints out statistics for all ids
81 -- TODO: make printout of tracked values do min/max
82 function instr_stats()
83 local total_time
= get_ticks() - temp_start
86 print(string.char(27).."[1;38;40m\nCALL STATISTICS")
87 print("==============="..string.char(27).."[0;38;40m")
88 for k
,v
in pairs(call_count
) do
89 print(string.char(27).."[1;32m"..k
..string.char(27).."[0;38;40m")
91 print("\tAvg: "..string.format("%3.4f",(run_time
[k
] or 1)/v
))
92 print("\t% total: "..string.format("%3.4f",(run_time
[k
] or 1)/total_time
))
96 print(string.char(27).."[1;38;40m\nVAR STATISTICS")
97 print("=============="..string.char(27).."[0;38;40m")
98 for k
,v
in pairs(var_track
) do
100 for i
,j
in pairs(v
) do
103 print(string.char(27).."[1;32m"..k
..string.char(27).."[0;38;40m: "..string.format("%3.4f",sum
/#v
))
107 --issue warnings about unended instrumentation runs
108 local unended
= false
109 for k
,v
in pairs(temp_time
) do
110 print(string.char(27).."[1;31mWARNING:"..string.char(27).."[0;38;40m Unended instrumentation: "..k
)
114 --issue big warning for unended instrumentations
115 if unended
== true then
116 print("\t*******************************************")
117 print("\t* There were unended instrumentations *")
118 print("\t* These statistics will NOT be accurate *")
120 print("\t* Review the above warnings and fix the *")
121 print("\t* related code to ensure proper profiling *")
122 print("\t*******************************************")
127 --log event - log stores timestamp and message, along with list of "classes"
128 -- the classes are passed as the extra arguments to the function
129 function instr_log(msg
,...)
132 for i
,v
in pairs(arg
) do
134 classes
= classes
..v
..",,"
138 event_log
[#event_log
+1] = {get_ticks(), classes
, msg
}
143 function instr_print_log(...)
148 class_string
= "All classes"
150 class_string
= "Classes:"
151 for i
,v
in pairs(arg
) do
153 classes
[#classes
+1] = v
154 class_string
= class_string
.." "..v
159 --print out entires that relate to the classes specified
160 print(string.char(27).."[1;38;40m\nEVENT LOG")
161 print("========="..string.char(27).."[0;38;40m")
162 print(string.char(27).."[1;32m"..class_string
..string.char(27).."[0;38;40m")
163 for k
,v
in pairs(event_log
) do
164 local matched
= false
165 for i
,j
in pairs(classes
) do
166 if string.match(v
[2],j
) then
171 --print out if the classes match
172 if matched
== true then
173 print(" "..v
[1]..": "..v
[3])