Rework profiler for 10.1.0
Since GetFunctionCPUUsage was removed in 10.1.0 the entire profler stopped working. This has been replaced by wrapping the functions in a closure that runs GetTimePreciseSec before and after and keeps track of the total runtime per function.
This commit is contained in:
115
src/profiler.lua
115
src/profiler.lua
@@ -26,56 +26,115 @@ local Printf = Commander.Printf
|
||||
|
||||
local types = omi.GetModule("types")
|
||||
local data = {}
|
||||
local startTime
|
||||
local stopTime
|
||||
local functionTimers = {}
|
||||
local functionNames = {}
|
||||
|
||||
Commander.RegisterCommand("omi-pstart", {
|
||||
description="Start/reset the OmicronFrames profiler",
|
||||
command=function()
|
||||
local profiler = C_CVar.GetCVar("scriptProfile")
|
||||
if profiler ~= "1" then
|
||||
PrintLn("scriptProfiler is off")
|
||||
PrintLn("set it to on with `/console scriptProfile 1`, then reload the UI.")
|
||||
-- Permanently wrap all functions to do profiling
|
||||
local function EnableFunctionProfiler()
|
||||
if #functionTimers ~= 0 then
|
||||
return
|
||||
end
|
||||
local GetTimePreciseSec = GetTimePreciseSec
|
||||
local counter = 1
|
||||
for typeName, T in pairs(types) do
|
||||
if type(T) == "table" then
|
||||
PrintLn("Type:", typeName, T)
|
||||
for fnName, fn in pairs(T) do
|
||||
if type(fn) == "function" then
|
||||
local fnIdx = counter
|
||||
counter = counter + 1
|
||||
local name = string.format("%s:%s", typeName, fnName)
|
||||
functionTimers[fnIdx] = 0
|
||||
functionNames[fnIdx] = name
|
||||
local wrapped = function(...)
|
||||
local start = GetTimePreciseSec()
|
||||
local a, b, c, d, e, f, g, h = fn(...)
|
||||
local elapsed = GetTimePreciseSec() - start
|
||||
functionTimers[fnIdx] = functionTimers[fnIdx] + elapsed
|
||||
return a, b, c, d, e, f, g, h
|
||||
end
|
||||
T[fnName] = wrapped
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Set all function timers back to 0
|
||||
local function ResetFunctionProfiler()
|
||||
for i, _ in ipairs(functionTimers) do
|
||||
functionTimers[i] = 0
|
||||
end
|
||||
end
|
||||
|
||||
Commander.RegisterCommand("omi-pstart", {
|
||||
description = "Start/reset the OmicronFrames profiler",
|
||||
command = function()
|
||||
local profiler = C_CVar.GetCVar("scriptProfile")
|
||||
PrintLn("OmicronFrames: start profiling")
|
||||
EnableFunctionProfiler()
|
||||
ResetFunctionProfiler()
|
||||
startTime = GetTimePreciseSec()
|
||||
stopTime = nil
|
||||
if profiler == "1" then
|
||||
ResetCPUUsage()
|
||||
else
|
||||
PrintLn("WoW scriptProfiler is off. Addon totals will not be shown,")
|
||||
PrintLn("only individual functions.The profiler will not show total")
|
||||
PrintLn("addon time, only function profiler.")
|
||||
PrintLn("")
|
||||
PrintLn("To enable the script profiler run `/console scriptProfile 1`, then reload the UI.")
|
||||
return
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
Commander.RegisterCommand("omi-pstop", {
|
||||
description="Stop the OmicronFrames profiler",
|
||||
command=function()
|
||||
description = "Stop the OmicronFrames profiler",
|
||||
command = function()
|
||||
if not startTime then
|
||||
PrintLn("Profiling not started. Run omi-pstart first.")
|
||||
return
|
||||
end
|
||||
PrintLn("OmicronFrames: stop profiling")
|
||||
local profiler = C_CVar.GetCVar("scriptProfile") == "1"
|
||||
data = {}
|
||||
stopTime = GetTimePreciseSec()
|
||||
if profiler then
|
||||
UpdateAddOnCPUUsage()
|
||||
local total = GetAddOnCPUUsage(addonName)
|
||||
data = {{
|
||||
table.insert(data, {
|
||||
name = "Total OmicronFrames time",
|
||||
time = total,
|
||||
pct = 1.0
|
||||
}}
|
||||
|
||||
for typeName, T in pairs(types) do
|
||||
if type(T) == "table" then
|
||||
for fnName, fn in pairs(T) do
|
||||
if type(fn) == "function" then
|
||||
local time = GetFunctionCPUUsage(fn, true)
|
||||
table.insert(data, {
|
||||
name = string.format("%s:%s", typeName, fnName),
|
||||
time = time,
|
||||
pct = time/total
|
||||
})
|
||||
end
|
||||
for i, time in ipairs(functionTimers) do
|
||||
local name = functionNames[i]
|
||||
table.insert(data, {
|
||||
name = name,
|
||||
time = time * 1000,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
table.sort(data, function(a, b) return a.time > b.time end)
|
||||
table.sort(data, function(a, b) return a.time < b.time end)
|
||||
end,
|
||||
})
|
||||
|
||||
Commander.RegisterCommand("omi-pprint", {
|
||||
description="Print the collected OmicronFrames profiling data",
|
||||
command=function()
|
||||
description = "Print the collected OmicronFrames profiling data",
|
||||
command = function()
|
||||
if not stopTime then
|
||||
PrintLn("Profiling data not collected yet. Run omi-pstop first.")
|
||||
return
|
||||
end
|
||||
local top = data[#data].time
|
||||
local total = stopTime - startTime
|
||||
for _, item in ipairs(data) do
|
||||
Printf("% 5.1f%% % 5fms %s\n", item.pct*100, item.time, item.name)
|
||||
local time = item.time
|
||||
local pct = time / top * 100
|
||||
local ms_per_sec = time / total
|
||||
Printf("% 6.1f%% % 7.2fms %7.2fms/s %s\n", pct, time, ms_per_sec, item.name)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
Reference in New Issue
Block a user