Originally Posted by Kanegasi
I feel it's important to point out that RAM usage is not a performance issue, except for leak cases such as this thread you created or playing WoW with less than 8GB of RAM. Many addons, "Details" being a great example, save on a lot of CPU by caching as much info as possible.
CPU will always be WoW's bottleneck. Do not be afraid to cache as much data as possible instead of querying the API. The less you do each frame, especially in combat, the better.
|
In my addon
Scorpio, I try to solve the performance problem not by less operations, but with a task schedule system to smoothing the operations like
Lua Code:
Scorpio "TestBigLoop" ""
__Async__()
function LongLoop()
local time = GetTime()
local prev = 0
for i = 1, 10^7 do
if i%10 == 0 then
Continue() -- The frame will freeze if miss this
if time ~= GetTime() then
-- Means the thread is resumed in the next frame through OnUpdate
time = GetTime()
-- Here is the current time and the cycle count of the previous phase
print(time, i - prev)
prev = i
end
end
end
end
LongLoop()
The function
LongLoop will be processed in a coroutine, and the
Continue method will yield it if there is no more time for tasks in the same frame and resume it in the next frame if there is enough time.
This is how the script runs in my old laptop(i5-3230M), I changed a setting to keep the fps to 60, so for one frame the loop will be processed for 2k6-4k times, with the task schedule system I can smooth all my addons to keep the high fps(for my old hardware).
Besides the
Continue, there are many others like
Wait to wait for several system events, so for me, I can re-code Terenna's code like :
Lua Code:
Scorpio "ShowPosition" ""
tCoordsFrame = UIParent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
tCoordsFrame:SetPoint("CENTER")
__Async__()
function RefreshPosition()
local GetBestMapForUnit = C_Map.GetBestMapForUnit
local MapRects = {}
local UnitPosition = UnitPosition
local GetWorldPosFromMapPos = C_Map.GetWorldPosFromMapPos
local CreateVector2D = CreateVector2D
while true do
if IsPlayerMoving() then
local mapID = GetBestMapForUnit('player')
local x, y = UnitPosition('player')
if x and mapID then
local rects = MapRects[mapID]
if not rects then
local _, topleft = GetWorldPosFromMapPos(mapID, CreateVector2D(0,0))
local _, bottomright = GetWorldPosFromMapPos(mapID, CreateVector2D(1,1))
bottomright:Subtract(topleft)
rects = { topleft.x, topleft.y, bottomright.x, bottomright.y }
MapRects[mapID] = rects
end
x, y = x - rects[1], y - rects[2]
x, y = y / rects[4], x / rects[3]
tCoordsFrame:SetFormattedText('%.1f, %.1f', x * 100, y * 100)
Delay(0.5) -- wait 0.5 sec
else
tCoordsFrame:SetText("")
-- wait player change zone
Wait("PLAYER_ENTERING_WORLD", "ZONE_CHANGED", "ZONE_CHANGED_INDOORS")
end
else
Wait("PLAYER_STARTED_MOVING") -- wait player move
end
end
end
RefreshPosition()
Although I need more codes(include the framework) to do the same operations, we still can gain better performance through carefully coroutine controls.