Loops Lua尾部调用vs循环

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

我正在用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
我想提出以下问题:

  • 是否正确使用/实施尾部呼叫消除?
    call[cmd]()
    是否会在堆栈中引入任何干扰,从而我不会利用尾部调用消除

  • 像下面这样使用循环是否更好?若有,原因为何

    repeat
      io.write ('% ')
      local cmd = io.read()
    
      -- do stuff
    until cmd == 'quit'
    
  • 在Lua编程中说明了

    尾部呼叫是伪装成呼叫的goto

    那么尾部调用和循环之间有什么具体区别吗

  • 多谢各位

    是否正确使用/实施尾部呼叫消除

    如果您询问根据Lua语法,最后对
    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