Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lua inner function vs module-level function

Tags:

lua

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
like image 582
johncage Avatar asked May 22 '11 09:05

johncage


1 Answers

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?
like image 145
JUST MY correct OPINION Avatar answered Oct 14 '22 17:10

JUST MY correct OPINION