+ Reply to Thread
Results 1 to 8 of 8

Thread: Events and Addon CPU

  1. #1
    Ascendant Credo's Avatar
    Join Date
    Jan 2011
    Posts
    4,172

    Default Events and Addon CPU

    It seems like Events can cause an Addon to really get up there in cpu usage. I'm trying to build a Unit Frame addon, and I'm pretty much done with the initial building of it. I just want to make it run well before I put it out there. Right now it can spike up to 40% Addon cpu usage with about 20 people around, also it seems to depend greatly on whether I have a target (and/or focus) or not. With a target it goes up much much higher (20%+) than if I don't (usually below 10%).

    I'm using Event.Unit.Add to detect a target. Right now the function that is called is this:

    Code:
    function MontUI.Target(a)
    	if a then
    		for _,k in pairs(a) do
    			
    			if k == "player.target" then
    				
    				MontUI.TargetHealth()
    				MontUI.TargetResource()
    				MontUI.TargetName()
    				MontUI.TargetIcon()
    			else
    				return
    			end
    		end
    	end
    end
    All of my code is set up so that if the event doesn't contain the correct unit (player, player.target, or focus) then it is kicked back.

    Is there any way to better optimize this code and get the Addon cpu usage down? Should I just have one call of Event.Unit.Add?
    Last edited by Credo; 04-05-2012 at 04:21 PM.
    Even free cost too much now

  2. #2
    Plane Walker Imhothar's Avatar
    Join Date
    Feb 2012
    Posts
    439

    Default

    How much CPU is used depends on what you do. Unit.Event.Add is a pretty frequent event.
    I can just tell that if every single unit frame always iterates over the entire unit table than it will certainly add up. Instead iterate the unit table only once and update the relevant frames:

    Code:
    frames = {
    	["player.target"] = TargetUnitFrame,
    	["group01"] = Group01UnitFrame,
    }
    
    function UnitAddEventHandler(units) do
    	for k, v in pairs(units) do
    		local frame = frames[v]
    		if(frame) then
    			frame:Update()
    		end
    	end
    end
    This changes complexity from O(n * k) to O(n) with n = numbr of units and k = number of frames. It also makes it quite easy to add new unit frames without changing much code. This is especially important for the even more frequent events Event.Unit.Detail.*

    Oh and btw, your code only checks the first element of a and ignores all other.
    Last edited by Imhothar; 04-05-2012 at 04:35 PM.

  3. #3
    Telaran
    Join Date
    Mar 2012
    Posts
    72

    Default

    You might want to take a look at Zorba's libunitchange.

    It's designed to send you an event when a specifier has a unit change. So you'd register player.target, and then hook up to the returned event, it'll give you the new value when it changes.

    However, it seems odd that you're burning that much CPU, you're code snippet looks fairly simple, especially as it only looks at the first entry from the event, it doesn't actually loop around (the return stops it looking at all the entries so you might miss a player.target change)

    I suspect the issue is perhaps elsewhere in your code, UI items can show up as quite a bit of CPU.
    Last edited by Mere; 04-05-2012 at 04:38 PM.

  4. #4
    Ascendant Credo's Avatar
    Join Date
    Jan 2011
    Posts
    4,172

    Default

    I'll see what I can do with libunitchange. Looking at it I'm not sure how it works, but I'm sure I'll get it down fast if I play around with it.

    My statement was never meant to check beyond the first element. That part is intentional.
    Even free cost too much now

  5. #5
    Ascendant Credo's Avatar
    Join Date
    Jan 2011
    Posts
    4,172

    Default

    Nevermind I have no clue how to use LibUnitChange
    Even free cost too much now

  6. #6
    Ascendant Credo's Avatar
    Join Date
    Jan 2011
    Posts
    4,172

    Default

    Nevermind again I was just overthinking it.
    Even free cost too much now

  7. #7
    Plane Touched Verea's Avatar
    Join Date
    Feb 2011
    Location
    Netherlands
    Posts
    200

    Default

    Code:
    function MontUI.Target(a)
    	if a then
    		for _,k in pairs(a) do
    			
    			if k == "player.target" then
    				
    				MontUI.TargetHealth()
    				MontUI.TargetResource()
    				MontUI.TargetName()
    				MontUI.TargetIcon()
    			else
    				return
    			end
    		end
    	end
    end
    [/quote]

    Are you sure you want to do this? This would always call return unless the first in the list is k. Just saying.
    Verae, level 60 Cleric @ Blightweald, Guild Master of Tea Club
    I want to fly like an eagle, to the sea.
    I want to fly like an eagle, let my spirit carry me.

  8. #8
    Shadowlander Rompa's Avatar
    Join Date
    Apr 2011
    Posts
    37

    Default

    I had the same performance problem, the event buff.remove was updating every unit frame (all 20) every time it fired, so i changed the code to only update the frame of the unit who the buff belongs, that caused the cpu usage to not spike (and sometimes freeze the game) anymore
    Some events are fired very often and you have to manage that, sometimes is not important to update every time you get the event, sometimes it is, but always think that every time you change something on screen it's slowing the code greatly so try to change only when needed

+ Reply to Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts