本地声明的 lua 函数是不是在每次传递时都会被解析?
Posted
技术标签:
【中文标题】本地声明的 lua 函数是不是在每次传递时都会被解析?【英文标题】:Do locally declared lua functions get parsed every time they are passed?本地声明的 lua 函数是否在每次传递时都会被解析? 【发布时间】:2021-10-11 18:47:33 【问题描述】:假设我在另一个经常被调用的函数中有一个本地声明的函数:
function outer()
-- Do stuff
local loop = true
while loop do -- for some reason
local function inner()
-- Do function stuff
end
-- Doing stuff
inner()
end
end
每次在运行时遇到内部函数时,是否都会重新创建、解析、处理所有内容?基本上,这种模式和声明单独的独立函数之间有什么性能差异吗?
function inner()
-- Do stuff
end
functions outer()
local loop = true
while loop do
inner()
end
end
【问题讨论】:
【参考方案1】:简短回答:不。
当你运行一个 Lua 块(一个块通常是一个文件,但有时是一个字符串)时,整个块在执行之前被编译成字节码。当您定义一个本地函数时,您正在将对该函数的字节码的引用分配给该函数的名称。 Lua 不会重新评估函数本身。
在您的第一个代码 sn-p 中,您可能会因将字节码引用分配给局部变量而受到轻微的性能损失。当然,您应该确定这一点。不知道 Lua 能不能把它优化掉。
请注意,闭包可以有不同的上值集,但仍然引用相同的函数字节码。
【讨论】:
【参考方案2】:除了 luther 提供的答案之外,还有更多内容,但您可能想知道它是否重要。我认为这对性能影响不大。
Lua 将编译每个功能块,但是当您使用本地函数时,每次调用特定代码时都必须执行 CLOSURE 指令和 MOVE 指令。添加 MOVE 是为了防止 CALL 指令将闭包弹出堆栈。我不相信 Lua 在任何情况下都优化了这一点。
如果您有一个全局函数或一个上值,它只需要使用 GETGLOBAL、GETTABUP 或 GETUPVALUE 指令来获取该值。
你可以在这里看到生成的字节码; https://luac.nl/s/473abd2a0bb427a31766ea917
【讨论】:
以上是关于本地声明的 lua 函数是不是在每次传递时都会被解析?的主要内容,如果未能解决你的问题,请参考以下文章