dav*_*ave 2 lua loops tail-call-optimization
我在Lua中编写了一个CLI模块,嵌入到C程序中.
我想知道什么是处理提示的最佳方法,在尾调用和循环之间进行选择.
作为尾部调用我会做这样的事情:
call = { help=function () print 'just ask politely' end }
function shell ()
io.write ('% ')
local cmd = io.read ()
if cmd ~= 'quit' then
call[cmd] () -- for simplicity assume call[cmd] is never nil
return shell ()
end
end
Run Code Online (Sandbox Code Playgroud)
我会问以下问题:
它是否正确使用/实现尾部调用消除?是否call[cmd] ()
在堆栈中引入任何干扰,以便我不会利用尾部消除功能?
使用如下循环更好吗?如果是,为什么?
repeat
io.write ('% ')
local cmd = io.read()
-- do stuff
until cmd == 'quit'
Run Code Online (Sandbox Code Playgroud)在Lua的编程中说明了
一尾调用是打扮成一个呼叫跳转.
那么尾调用和循环之间有什么具体的区别吗?
谢谢.
Nic*_*las 10
它是否正确使用/实现尾部调用消除?
如果你shell
根据Lua语法询问最后的调用是否是正确的尾调用,答案是肯定的.
call [cmd]()是否会在堆栈中引入任何干扰,这样我就不会利用尾部调用消除?
函数调用不会以您的思维方式修改堆栈.在Lua中,尾调用的唯一要求是它具有形式return Function(params)
,没有额外的返回值不是函数的返回值.
正确的尾调甚至不需要自己调用; 它不需要递归.
使用如下循环更好吗?如果是,为什么?
这是一个主观点.就个人而言,我会说循环更清楚正在发生什么.
但是,如果你想要一个客观的性能问题,请考虑这一点:尾调用永远不会比循环更快.在性能方面你所获得的绝对最佳是平等的.
它可能不会那样.Lua尾调用"优化"只是意味着它重用当前函数的堆栈条目.Lua仍然需要从全局表中获取该函数.Lua仍然需要完成调用函数的所有开销; 它只是没有分配更多的堆栈内存.
它实际上是关于不会溢出堆栈而不是在不必要时分配内存.
尾调用和循环之间有什么具体的区别吗?
往上看.