1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
--[[
This is a reference implementation of a profile reporter using the ScriptProfiler API.
You can use it as an example of you how you can get useful results from the API, but alternate reporters
should be implemented in terms of the API, and not the functions defined here.
Usage:
to start collecting data:
StartScriptProfiler()
to stop:
StopScriptProfiler()
To print a report out to chat:
ZO_ScriptProfiler_GenerateReport()
--]]
local g_generatingReport = false
if g_generatingReport then
return
end
g_generatingReport = true
local numRecords = 0
local timeSpent = 0
local recordDataByRecordDataType =
{
[ SCRIPT_PROFILER_RECORD_DATA_TYPE_CLOSURE ] = { } ,
[ SCRIPT_PROFILER_RECORD_DATA_TYPE_CFUNCTION ] = { } ,
[ SCRIPT_PROFILER_RECORD_DATA_TYPE_GARBAGE_COLLECTION ] = { } ,
[ SCRIPT_PROFILER_RECORD_DATA_TYPE_USER_EVENT ] = { } ,
}
if not recordDataByRecordDataType [ recordDataType ] [ recordDataIndex ] then
{
dataType = recordDataType ,
includeTime = 0 ,
excludeTime = 0 ,
}
if recordDataType == SCRIPT_PROFILER_RECORD_DATA_TYPE_CLOSURE then
-- Closures are functions defined in Lua. Functions defined in the same file, on the same line, are considered the same function by the profiler.
elseif recordDataType == SCRIPT_PROFILER_RECORD_DATA_TYPE_CFUNCTION then
-- C Functions are functions defined by ZOS as part of the game's API.
elseif recordDataType == SCRIPT_PROFILER_RECORD_DATA_TYPE_GARBAGE_COLLECTION then
-- At arbitrary times, the lua intepreter will automatically try to reclaim memory you are no longer using. When it does this we generate a GC event to track it.
data . name = GetScriptProfilerGarbageCollectionInfo ( recordDataIndex ) == SCRIPT_PROFILER_GARBAGE_COLLECTION_TYPE_AUTOMATIC and "Lua GC Step" or "Manual collectgarbage() GC step"
elseif recordDataType == SCRIPT_PROFILER_RECORD_DATA_TYPE_USER_EVENT then
-- You can fire off your own custom events using RecordScriptProfilerUserEvent(myEventString). Events with the same eventString will share a recordDataIndex.
else
end
end
return recordDataByRecordDataType [ recordDataType ] [ recordDataIndex ]
end
local recordDataIndex , startTimeNS , endTimeNS , calledByRecordIndex , recordDataType = GetScriptProfilerRecordInfo ( frameIndex , recordIndex )
local timeMS = ( endTimeNS - startTimeNS ) / ( 1000 * 1000 )
source . includeTime = source . includeTime + timeMS
source . excludeTime = source . excludeTime + timeMS
timeSpent = timeSpent + timeMS
if calledByRecordIndex then
-- get caller, and exclude the current record's time from it. By the end, the only time that will be left is time spent exclusively in the caller and not in the callees.
local calledByRecordDataIndex , _ , _ , _ , calledByRecordDataType = GetScriptProfilerRecordInfo ( frameIndex , calledByRecordIndex )
calledByData . excludeTime = calledByData . excludeTime - timeMS
end
end
local sorted = { }
end
end
return a . excludeTime > b . excludeTime
end )
-- Print backwards, so the first element is at the bottom of chat
end
local totals =
{
numRecords = numRecords ,
}
g_generatingReport = false
end
do
-- This splits up the work you would otherwise do as:
-- for frameIndex = 1, GetScriptProfilerNumFrames() do
-- for recordIndex = 1, GetScriptProfilerFrameNumRecords(frameIndex) do
-- ...
-- end
-- end
local frameIndex = 1
local recordIndex = 1
local RECORDS_PER_UPDATE = 100000 -- Arbitrarily chosen number, tune to workload
for _ = 1 , RECORDS_PER_UPDATE do
if recordIndex > numFrameRecords then
frameIndex = frameIndex + 1
recordIndex = 1
end
if frameIndex > numFrames then
return
end
numRecords = numRecords + 1
recordIndex = recordIndex + 1
end
end )
end
end |