WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   declaring local variables inside functions? (https://www.wowinterface.com/forums/showthread.php?t=36564)

SaraFdS 11-05-10 10:30 PM

declaring local variables inside functions?
 
A simple(?) question that just came to my mind, when using local variables inside local functions, what's the most efficient and/or fastest way to do so?
Declare it once, outside the function
Code:

local foo = SomeValue
local function goo()
foo = SomeValue
-- do sth w/ foo
end

or declare it each time anew inside the function?
Code:

local function goo()
local foo = SomeValue
-- do sth w/ foo
end


Beoko 11-05-10 10:47 PM

For most cases, it is just an issue of scope. If you don't need the variable outside of the function, then it may as well be declared inside of the function. If it serves a purpose outside of the function, then you don't have much of a choice!

I think a case was made a while back for functions that are executed extremely frequently (such as inside of an OnUpdate handler) that it would be more beneficial to use upvalues rather than redeclaring local variables with each execution. I can't remember if an overall consensus was reached or the actual numbers regarding it, though. Perhaps someone else could shed more light on this.

Seerah 11-05-10 11:12 PM

Yes, I do believe that it is better to declare the variable outside of a function that is called frequently, such as an OnUpdate, or for an event that gets called frequently (UNIT_AURA, CLEU, etc)

If I recall correctly, every time your function says
local var = foo
you are creating a new variable in memory (which just happens to be named the same as the old one, and thus overwrites it) instead of just reassigning the original variable.

As mentioned, though, if it is a matter of scope, then that is where to consider where to declare which variables.

Xinhuan 11-05-10 11:29 PM

That's not true. When you use a local variable, the memory allocated for it is on the stack (by default Lua allows a maximum of 200 locals and function parameters).

When you declare an upvalue, that upvalue was initially a function (or chunk) local. When the function (chunk) returns and the variable is still in the scope of some closure, that variable is moved from the stack to the heap and future accesses to it from the closure costs an indirection.

I.e Using upvalues costs an extra 4 bytes of memory for the indirection, and is about 1 clock cycle slower. Obviously it doesn't really matter, since this is in nanoseconds.

Beoko 11-06-10 01:07 AM

Thank you for the clarification, Xinhuan. For further elaboration: Will local variables will always be cheaper regardless of the execution time (such as in the previous mentions of OnUpdate handlers and the fast firing events)? If that's the case, then it seems that upvalues have no real advantages over locals other than scope, obviously.

I can't remember when or where that aforementioned discussion took place, so I suppose it's not too far-fetched to assume that I interpreted it incorrectly as well.

Edit: Gah it's too late, I'm going to have to reread this later when I can actually think.:(

Xinhuan 11-06-10 04:48 AM

Basically, use locals where possible, they are on the stack and gets cleaned when the function returns. The main reason to use upvalues is to share or store data in a scope larger than a function itself.


Use upvalues in these cases:
A) Data needs to be shared across multiple functions. In this case, your upvalue could be as simple as just being a boolean, or it can be as complex as a complete table (such as your SavedVariables).

B) Data or intermediate results doesn't need to be shared, but is expensive to calculate on demand. Thus you want to cache them as upvalues to reuse them inexpensively.

Here's a somewhat contrived example:

Code:

for i = 1, 40 do
    local unitID = format("raid%d", i)
    -- Do stuff with unitID
end

Now clearly recreating the strings "raid1" through "raid40" via the format() function or string..integer concatenation is somewhat expensive compared to this

Code:

-- At the top of the file
local RaidIDs = {}
for i = 1, 40 do
    RaidIDs[i] = format("raid%d", i)
end

-- Later in some function or OnUpdate or very frequent event handler
for i = 1, 40 do
    local unitID = RaidIDs[i]
    -- Do stuff with unitID
end

We cached the 40 unitID strings in a table and simply used it later. This is just another example of the memory vs speed problem in programming.

SaraFdS 11-06-10 07:34 AM

Alright, seems like it's not that simple a question, thanks for your input.

Mischback 11-07-10 01:11 AM

It is a very basic programming question and it's simple to answer:

Keep scope as minimal as possible, just as Xinhuan said.

Xinhuan aswell stated very clear, in which cases a larger scope is needed / can be useful.

But the bottomline is: Small scope = good!


All times are GMT -6. The time now is 08:02 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI