Lua 中的 Profiler |
|
(它在大約 12 分鐘內編寫完成,因此請陪我耐心一點。--Pedro)
用法:呼叫 Profiler:activate()
開始測量,Profiler:deactivate()
停止測量,然後 Profiler:print_results()
查看結果。調整 print 函數以滿足您的喜好進行排序等操作。
請注意,透過使用非 ANSI 且精度為毫秒的函數來覆蓋 os.time()
,可以增強該功能。不過,對於我的應用程式來說,秒已經足夠用來找出使時間變成二次函數而不是線性函數的行。
另外請注意,它現在只能測量程式碼執行次數和時間。如有必要,可以延伸它來呼叫函式執行。已作了一些準備,但還遠遠不夠。
--| Profiler module. --b "Pedro Miller Rabinovitch" <miller@inf.puc-rio.br> --$Id: prof.lua,v 1.4 2003/10/17 00:17:21 miller Exp $ --TODO add function call profiling. Some of the skeleton is already in --- place, but call profiling behaves different, so a couple of new --- functionalities must be added. --TODO add methods for proper result retrieval --TODO use optional clock() function for millisecond precision, if it's --- available local E, I = {}, {} --& Profiler module. Profiler = E --. Keeps track of the hit counts of each item E.counts = { line = {} } --. These should be inside the _line_ table above. E.last_line = nil E.last_time = os.time() E.started, E.ended = nil, nil --% Activates the profiling system. --@ [kind] (string) Optional hook kind. For now, only 'line' works, --- so just avoid it. >: ) function E:activate( kind ) kind = kind or 'line' local function hook_counter( hk_name, param,... ) local t = self.counts[hk_name][param] if t == nil then t = { count=0, time = 0 } self.counts[hk_name][param] = t end self.counts[hk_name][param].count = self.counts[hk_name][param].count + 1 if self.last_line then local delta = os.time() - self.last_time if delta > 0 then self.counts[hk_name][self.last_line].time = self.counts[hk_name][self.last_line].time + delta self.last_time = os.time() end end self.last_line = param end self.started = os.time() debug.sethook( hook_counter, kind ) end --% Deactivates the profiling system. --@ [kind] (string) Optional hook kind. For now, only 'line' works, --- so just avoid it. function E:deactivate( kind ) kind = kind or 'line' self.ended = os.time() debug.sethook( nil, kind ) end --% Prints the results. --@ [kind] (string) Optional hook... Aah, you got it by now. --TODO add print output formatting and sorting function E:print_results( kind ) kind = kind or 'line' print( kind, 'count', 'approx. time (s)' ) print( '----', '-----', '----------------' ) for i,v in pairs( self.counts[kind] ) do print( i, v.count, v.time ) end print( self.ended - self.started, ' second(s) total (approximately).' ) end