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:
- 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.)
- 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.)
- 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.)
- 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.
精彩评论