lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



Thank you for the reply

On 18/09/2011 12.31, David Kastrup wrote:
[...]


Uh what? "local e" is a declaration.  It does not generate code but is
merely executed in the compiler.  And Lua does not recompile a loop for
every iteration.  That would be stupid.
Yes. I didn't mean or think it generates code at every iteration, but doesn't the execution of

local x

allocate some stack space?

If I write:

local x
local x
local x
local x = 1

this is not the same as simply

local x = 1

i.e. even if the declarations are all in the same scope, they don't refer to the same stack slot (or not?)



But recently by chance I compared the "disassembled code" for those
two functions, and they look almost the same to me (the case was more
complex, with more locals - I stripped it down to reduce clutter
here):

For readability and for scope minimization I would like to use the
style of f2, but I learned to use the style of f1 (predeclaring all
the temporary locals used in the loop) when performance could be at
stake.

I cannot trace back where first I learned to do that, but I fear now I
have interpreted wrongly some optimization tip.

I guess so.  It is rather the other way round.  By importing variables
into blocks, you run the risk of getting upvalues.

Sorry I don't understand you here. What do you mean by "importing into a block"? I (wrongly) tried to optimize a loop by "pulling out" a local declaration from its body. The block you are referring to is the loop body?

To be clear, are you saying that

for i=1,n do
  local tmp = exp -- exp computes an intermediate result
  ...
  -- here I use tmp in other computations
end

is less risky (besides being more readable) than predeclaring tmp out of the loop? Did I get it right?


Am I missing something (I'm not an expert of Lua VM so I may have
missed something related to the meaning of the instructions operands
in the listings above)?

You are missing something.  local x does not generate code, it merely
tells the compiler something about how to generate code.  local x =
expr, in contrast, also has a runtime component.  It will reevaluate the
expression every time you run over that code when looping.  It will not
rethink the scoping, however.


Sorry for the doubt, but how then, if "local e" doesn't generate a new local at every iteration, the following loop works? Here e is an upvalue for the closures being created in the loop, but it appears there are three different upvalues (one for each closure):

local array = { 'a', 'b', 'c' }
local t = {}
for i = 1, #array do
   local e
   e = array[ i ]
   t[i] = function()
      print( e )
   end
end

t[1]() --> 'a'
t[2]() --> 'b'
t[3]() --> 'c'

if I move the "local e" declaration out of the loop, then the calls all print 'c'. So it seems that "local e" *has* a runtime effect. I'm puzzled!