源战役客户端
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 

228 行
6.2 KiB

LuaProfiler = {}
LuaProfiler.is_playing = false
function LuaProfiler.SwitchState()
LuaProfiler.is_playing = not LuaProfiler.is_playing
if LuaProfiler.is_playing then
LuaProfiler.start()
else
LuaProfiler.stop()
end
end
-- get the function title
function LuaProfiler._func_title(funcinfo)
-- check
assert(funcinfo)
-- the function name
local name = funcinfo.name or 'none_name'
-- the function line
-- print("_func_title = ", name)
local line = string.format("%d", funcinfo.linedefined or 0)
-- the function source
local source = funcinfo.short_src or 'C_FUNC'
-- if os.isfile(source) then
-- source = path.relative(source, xmake._PROGRAM_DIR)
-- end
-- make title
return string.format("%-30s: %s: %s", name, source, line), source
end
-- get the function report
function LuaProfiler._func_report(funcinfo)
-- get the function title
local title, source = LuaProfiler._func_title(funcinfo)
-- get the function report
local report = LuaProfiler._REPORTS_BY_TITLE[title]
if not report then
-- init report
report =
{
title = LuaProfiler._func_title(funcinfo)
, source = source
, callcount = 0
, totaltime = 0
}
-- save it
LuaProfiler._REPORTS_BY_TITLE[title] = report
table.insert(LuaProfiler._REPORTS, report)
end
-- ok?
return report
end
-- profiling call
function LuaProfiler._profiling_call(funcinfo)
-- get the function report
local report = LuaProfiler._func_report(funcinfo)
assert(report)
-- save the call time
report.calltime = os.clock()
-- update the call count
report.callcount = report.callcount + 1
end
-- profiling return
function LuaProfiler._profiling_return(funcinfo)
-- get the stoptime
local stoptime = os.clock()
-- get the function report
local report = LuaProfiler._func_report(funcinfo)
assert(report)
-- update the total time
if report.calltime and report.calltime > 0 then
report.totaltime = report.totaltime + (stoptime - report.calltime)
report.calltime = 0
end
end
-- the profiling handler
function LuaProfiler._profiling_handler(hooktype)
-- the function info
local funcinfo = debug.getinfo(2, 'nS')
-- print("_profiling_handler = ", hooktype)
-- dispatch it
if hooktype == "call" then
LuaProfiler._profiling_call(funcinfo)
elseif hooktype == "return" then
LuaProfiler._profiling_return(funcinfo)
end
end
-- the tracing handler
function LuaProfiler._tracing_handler(hooktype)
-- the function info
local funcinfo = debug.getinfo(2, 'nS')
-- is call?
if hooktype == "call" then
-- is xmake function?
local name = funcinfo.name
local source = funcinfo.short_src or 'C_FUNC'
if name then-- and os.isfile(source) then
-- the function line
local line = string.format("%d", funcinfo.linedefined or 0)
-- get the relative source
-- source = path.relative(source, xmake._PROGRAM_DIR)
-- trace it
print(string.format("%-30s: %s: %s", name, source, line))
end
end
end
-- start profiling
function LuaProfiler.start(mode)
-- trace?
if mode and mode == "trace" then
debug.sethook(LuaProfiler._tracing_handler, 'cr', 0)
else
-- init reports
LuaProfiler._REPORTS = {}
LuaProfiler._REPORTS_BY_TITLE = {}
LuaProfiler._CUSTOM_REPORTS = ""
print("----------------------------------------------->>LuaProfiler.start")
-- save the start time
LuaProfiler._STARTIME = os.clock()
-- start to hook
debug.sethook(LuaProfiler._profiling_handler, 'cr', 0)
end
end
-- stop profiling
function LuaProfiler.stop(mode)
-- trace?
if mode and mode == "trace" then
-- stop to hook
debug.sethook()
else
print("----------------------------------------------->>LuaProfiler.stop")
-- save the stop time
LuaProfiler._STOPTIME = os.clock()
-- stop to hook
debug.sethook()
-- calculate the total time
local totaltime = LuaProfiler._STOPTIME - LuaProfiler._STARTIME
print("totaltime = " , totaltime)
-- sort reports
table.sort(LuaProfiler._REPORTS, function(a, b)
return a.totaltime > b.totaltime
end)
-- show reports
local total_percent = 0
local class_list = {}
for _, report in ipairs(LuaProfiler._REPORTS) do
-- calculate percent
local percent = (report.totaltime / totaltime) * 100
total_percent = total_percent + percent
if percent < 0.1 then
break
end
local vo = class_list[report.source]
if vo == nil then
vo = {}
class_list[report.source] = vo
vo.totaltime = 0
vo.percent = 0
vo.callcount = 0
end
vo.totaltime = vo.totaltime + report.totaltime
vo.percent = vo.percent + percent
vo.callcount = vo.callcount + report.callcount
-- trace
local temp_str = string.format("totaltime = %6.3f, percent = %6.2f%%, count =%7d, pos = %s", report.totaltime, percent, report.callcount, report.title)
-- print(temp_str)
LuaProfiler._CUSTOM_REPORTS = LuaProfiler._CUSTOM_REPORTS .. temp_str .."\n"
end
print("----------------------------------------------->>class_list")
local new_list = {}
for k,v in pairs(class_list) do
v.source = k
table.insert(new_list, v)
end
table.sort(new_list, function(a, b)
return a.totaltime > b.totaltime
end)
for source, info in ipairs(new_list) do
local temp_str = string.format("totaltime = %6.3f, percent = %6.2f%%, count =%7d, pos = %s", info.totaltime, info.percent, info.callcount, info.source)
-- print(temp_str)
LuaProfiler._CUSTOM_REPORTS = LuaProfiler._CUSTOM_REPORTS .. temp_str .."\n"
end
end
end