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:
103
src/profiler.lua
103
src/profiler.lua
@@ -26,56 +26,115 @@ local Printf = Commander.Printf
|
|||||||
|
|
||||||
local types = omi.GetModule("types")
|
local types = omi.GetModule("types")
|
||||||
local data = {}
|
local data = {}
|
||||||
|
local startTime
|
||||||
|
local stopTime
|
||||||
|
local functionTimers = {}
|
||||||
|
local functionNames = {}
|
||||||
|
|
||||||
|
-- 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", {
|
Commander.RegisterCommand("omi-pstart", {
|
||||||
description = "Start/reset the OmicronFrames profiler",
|
description = "Start/reset the OmicronFrames profiler",
|
||||||
command = function()
|
command = function()
|
||||||
local profiler = C_CVar.GetCVar("scriptProfile")
|
local profiler = C_CVar.GetCVar("scriptProfile")
|
||||||
if profiler ~= "1" then
|
PrintLn("OmicronFrames: start profiling")
|
||||||
PrintLn("scriptProfiler is off")
|
EnableFunctionProfiler()
|
||||||
PrintLn("set it to on with `/console scriptProfile 1`, then reload the UI.")
|
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
|
return
|
||||||
end
|
end
|
||||||
PrintLn("OmicronFrames: start profiling")
|
|
||||||
ResetCPUUsage()
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
Commander.RegisterCommand("omi-pstop", {
|
Commander.RegisterCommand("omi-pstop", {
|
||||||
description = "Stop the OmicronFrames profiler",
|
description = "Stop the OmicronFrames profiler",
|
||||||
command = function()
|
command = function()
|
||||||
|
if not startTime then
|
||||||
|
PrintLn("Profiling not started. Run omi-pstart first.")
|
||||||
|
return
|
||||||
|
end
|
||||||
PrintLn("OmicronFrames: stop profiling")
|
PrintLn("OmicronFrames: stop profiling")
|
||||||
|
local profiler = C_CVar.GetCVar("scriptProfile") == "1"
|
||||||
|
data = {}
|
||||||
|
stopTime = GetTimePreciseSec()
|
||||||
|
if profiler then
|
||||||
UpdateAddOnCPUUsage()
|
UpdateAddOnCPUUsage()
|
||||||
local total = GetAddOnCPUUsage(addonName)
|
local total = GetAddOnCPUUsage(addonName)
|
||||||
data = {{
|
table.insert(data, {
|
||||||
name = "Total OmicronFrames time",
|
name = "Total OmicronFrames time",
|
||||||
time = total,
|
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
|
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)
|
||||||
end
|
|
||||||
table.sort(data, function(a, b) return a.time > b.time end)
|
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
Commander.RegisterCommand("omi-pprint", {
|
Commander.RegisterCommand("omi-pprint", {
|
||||||
description = "Print the collected OmicronFrames profiling data",
|
description = "Print the collected OmicronFrames profiling data",
|
||||||
command = function()
|
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
|
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
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user