Thread Tools Display Modes
11-05-10, 10:30 PM   #1
SaraFdS
A Fallenroot Satyr
 
SaraFdS's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 24
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
__________________
Sará the Insane
  Reply With Quote
11-05-10, 10:47 PM   #2
Beoko
Guest
Posts: n/a
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.

Last edited by Beoko : 11-05-10 at 10:51 PM.
  Reply With Quote
11-05-10, 11:12 PM   #3
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
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.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
11-05-10, 11:29 PM   #4
Xinhuan
A Chromatic Dragonspawn
 
Xinhuan's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 174
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.
__________________
Author of Postal, Omen3, GemHelper, BankItems, WoWEquip, GatherMate, GatherMate2, Routes and Cartographer_Routes

Last edited by Xinhuan : 11-05-10 at 11:31 PM.
  Reply With Quote
11-06-10, 01:07 AM   #5
Beoko
Guest
Posts: n/a
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.
  Reply With Quote
11-06-10, 04:48 AM   #6
Xinhuan
A Chromatic Dragonspawn
 
Xinhuan's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 174
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.
__________________
Author of Postal, Omen3, GemHelper, BankItems, WoWEquip, GatherMate, GatherMate2, Routes and Cartographer_Routes

Last edited by Xinhuan : 11-06-10 at 04:50 AM.
  Reply With Quote
11-06-10, 07:34 AM   #7
SaraFdS
A Fallenroot Satyr
 
SaraFdS's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 24
Alright, seems like it's not that simple a question, thanks for your input.
__________________
Sará the Insane
  Reply With Quote
11-07-10, 01:11 AM   #8
Mischback
A Cobalt Mageweaver
 
Mischback's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 221
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!
__________________
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » declaring local variables inside functions?


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off