Question on local variables and memory leaks

Hi there,

I’m new to Lua and Corona and I was wondering if I need to set to nil all the local variables I use within a function or if they are disposed by the garbage collector later on.

I read as well on the optimisation recommendations article in Corona University the following:

In time-critical routines, you should always localize library functions.

–NON-LOCAL (DISCOURAGED)
local function foo( x )
for i = 1,100 do
x = x + math.sin(i)
end
return x
end

–“EXTERNAL” LOCAL (RECOMMENDED)
local sin = math.sin --local reference to ‘math.sin’
local function foo(x)
for i = 1,100 do
x = x + sin(i)
end
return x
end

So my question is, why is that? And if would I have to set to nil the local sin variable that is created in the example in some moment and if I wouldn’t how this would affect performance.

Thanks a lot for your help :smiley:

Seems like you have two questions…

local function doSometing()

    local someVariable = 10

    local someObject = object.new()

end

In this case, there are two local variables to the doSomething function.  Both are 4 byte long (i.e. 32 bit) chunks of memory.    The first one holds a simple variable.  The second one holds an address to to the object.   The first one does not allocate any memory beyond the 4 bytes.  The second one returns a table which probably has allocated memory.   The two variable’s 4 bytes will get zeroed and reused the next time the function is called.   In this case, any allocated memory done by object.new() will still be allocated and since the address to that memory was lost (never returned to the caller), its now a memory leak.   You should make sure you have a way to access allocated memory or free it and set it to nil when you are done.

The second question has to do with why localizing table members is better.

When you reference math.sin(), math happens to be a global variable, which takes time to look up.  Globals are the slowest memory addresses for the system to index. 

But in the case of any table member (lets for the moment assume math.* isn’t global), its still more efficient to localize the memory.  Consider this:

for i  = 1, 10000 do

     print( math.sin( i ) )

end

There will be 10,000 times where the code has to find the math table object and traverse it’s index looking for the “sin” entry to get the address of the function to run.  It’s a quick thing to do, but when its done a lot it adds up.  Now consider:

local sin = math.sin

for i = 1, 10000 do

     print( sin( i ) )

end

Now you only have to traverse the math object once and now you have the address of the sin() function.  Each iteration through the loop doesn’t have to do the look up.

If your app only calls sin() a few times, it’s a very insignificant gain, but if you’re doing a bunch of trig to move a bunch of enemies on the screen traversing the math object to get to the functions is measurable.

Rob

Thanks for your clear answer Rob, it helped a lot :smiley:

Seems like you have two questions…

local function doSometing()

    local someVariable = 10

    local someObject = object.new()

end

In this case, there are two local variables to the doSomething function.  Both are 4 byte long (i.e. 32 bit) chunks of memory.    The first one holds a simple variable.  The second one holds an address to to the object.   The first one does not allocate any memory beyond the 4 bytes.  The second one returns a table which probably has allocated memory.   The two variable’s 4 bytes will get zeroed and reused the next time the function is called.   In this case, any allocated memory done by object.new() will still be allocated and since the address to that memory was lost (never returned to the caller), its now a memory leak.   You should make sure you have a way to access allocated memory or free it and set it to nil when you are done.

The second question has to do with why localizing table members is better.

When you reference math.sin(), math happens to be a global variable, which takes time to look up.  Globals are the slowest memory addresses for the system to index. 

But in the case of any table member (lets for the moment assume math.* isn’t global), its still more efficient to localize the memory.  Consider this:

for i  = 1, 10000 do

     print( math.sin( i ) )

end

There will be 10,000 times where the code has to find the math table object and traverse it’s index looking for the “sin” entry to get the address of the function to run.  It’s a quick thing to do, but when its done a lot it adds up.  Now consider:

local sin = math.sin

for i = 1, 10000 do

     print( sin( i ) )

end

Now you only have to traverse the math object once and now you have the address of the sin() function.  Each iteration through the loop doesn’t have to do the look up.

If your app only calls sin() a few times, it’s a very insignificant gain, but if you’re doing a bunch of trig to move a bunch of enemies on the screen traversing the math object to get to the functions is measurable.

Rob

Thanks for your clear answer Rob, it helped a lot :smiley: