开发者

Lua inner function vs module-level function

For a function inside another function, does Lua "instantiate" the inner function on each call to the outer function? If so, would bar() in the code below perform worse than foo()?

local function a()
  print 'a'
end

function foo()
  a()
end

function bar开发者_如何学编程()
  function b()
    print 'b'
  end

  b()
end


Test case 1: a and b both global, no embedding.

$ cat junk.lua ; time lua junk.lua
function a(n)
    return n + 1
end

function b(n)
    return a(n)
end

for c = 1, 10000000 do
    b(c)
end


real    0m1.743s
user    0m1.740s
sys 0m0.000s

User time: 1.74s.

Test case 2: a local, b global, no embedding.

local function a(n)
    return n + 1
end

function b(n)
    return a(n)
end

for c = 1, 10000000 do
    b(c)
end


real    0m1.388s
user    0m1.390s
sys 0m0.000s

User time 1.39s.

Test case 3: a and b both local, no embedding.

$ cat junk.lua ; time lua junk.lua
local function a(n)
    return n + 1
end

local function b(n)
    return a(n)
end

for c = 1, 10000000 do
    b(c)
end


real    0m1.194s
user    0m1.200s
sys 0m0.000s

User time 1.2s.

Test case 4: a embedded in b, a global, b local.

$ cat junk.lua ; time lua junk.lua
local function b(n)
    function a(n)
        return n + 1
    end

    return a(n)
end

for c = 1, 10000000 do
    b(c)
end


real    0m2.804s
user    0m2.790s
sys 0m0.000s

User time: 2.79s. (!)

Test case 5: a embedded in b, both local.

$ cat junk.lua ; time lua junk.lua
local function b(n)
    local function a(n)
        return n + 1
    end

    return a(n)
end

for c = 1, 10000000 do
    b(c)
end


real    0m2.540s
user    0m2.530s
sys 0m0.000s

User time: 2.53s.

Result summary:

  1. It's easy to write tests to confirm or deny intuitions about performance. You should probably do this instead of relying on crowd-sourcing the answer. (The crowd is often wrong, you see.)
  2. Making functions local instead of global has a significant positive impact on function call overhead. (About 30% better in this set of test cases when both functions were local.)
  3. Embedding a function in another function has a serious negative impact on function call overhead. (About 110% worse in this set of test cases when both functions were local.)
  4. Did I mention that testing is probably a good idea in lieux of trusting the crowd?


bar will be slower because you are creating a new function object every time. If you want to declare functions inside a function you probably want to return a closure.

local bar = function()
  local f = function()
    -- Lots of stuff...
  end
  local g = function()
    -- Also lots of stuff
  end
  return function()
    -- Do something with f and g...
  end
end

local created_f = bar()
created_f()
created_f()  -- Now you can skip the function initialization.


Roberto has written a pretty comprehensive article on Lua Performance Tips like this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜