Loops Lua尾部调用vs循环
我正在用Lua编写一个小的CLI模块,嵌入到C程序中 我想知道处理提示的最佳方法是什么,在尾部调用和循环之间进行选择 作为尾部呼叫我会这样做:Loops Lua尾部调用vs循环,loops,lua,tail-call-optimization,Loops,Lua,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 sim
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
我想提出以下问题:
call[cmd]()
是否会在堆栈中引入任何干扰,从而我不会利用尾部调用消除repeat
io.write ('% ')
local cmd = io.read()
-- do stuff
until cmd == 'quit'
shell
的调用是否是正确的尾部调用
调用[cmd]()是否会在堆栈中引入任何干扰,从而我不会利用尾部调用消除
函数调用不会以您的思维方式修改堆栈。在Lua中,tail调用的唯一要求是其形式为返回函数(params)
,没有不是函数返回值的额外返回值
一个正确的尾部呼叫甚至不需要自己呼叫;它不需要是递归的
使用如下循环是否更好?若有,原因为何
repeat
io.write ('% ')
local cmd = io.read()
-- do stuff
until cmd == 'quit'
这是一个主观的观点。就我个人而言,我想说的是,这个循环对于正在发生的事情更加清晰
但是,如果你想要一个性能的客观问题,考虑一下:尾调用永远不会比循环快。就性能而言,您将获得的绝对最佳性能是相等的
可能不会是这样。LuaTail调用“优化”仅仅意味着它重用当前函数的堆栈项。Lua仍然必须从全局表中获取函数。Lua仍然需要完成调用函数的所有开销;它不需要分配更多的堆栈内存 它实际上是关于不溢出堆栈,不在不必要的时候分配内存 尾部调用和循环之间有什么具体区别吗参见上文。您可以更清楚地解释我的意思+所以在很多情况下,Lua中的尾部递归函数可能比循环函数慢。但是考虑需要处理VARARGS或多个返回值的情况。code>函数recurse(n,i,sum,val,…)如果n==i则返回i+sum end return recurse(n,i+1,sum+val,…)end将其称为
recurse(n,1,…)
在普通Lua中,这比在表上循环要慢一点,但不要忘记每次完成后都必须创建、初始化和收集该表。在LuaJIT中,此代码实际上比在数组上循环快几个数量级。对不起,应该是:如果n==i,则返回val+sum end
。