繁体   English   中英

JavaScript中的尾递归优化

[英]Tail recursion optimization in JavaScript

如果它是块(IIUC)中的最后一个表达式,JavaScript将仅优化为非递归循环的递归步骤。 这是否意味着右手递归调用将被优化,左手递归调用将不会在下面?

function fibonacci(n) {
  if(n < 2) return n;
  return fibonacci(n-1) + fibonacci(n-2);
}

这是否意味着右手递归调用将被优化,左手递归调用将不会在下面?

我不这么认为。 只有在您直接返回其他函数返回的内容时才可以使用TCO。 由于您的函数在返回结果之前处理两个结果,因此这两个调用都不能进行尾部优化。

低级别的解释

就基于堆栈的机器而言,代码如下:

function fun1()
   return fun2(42)

function fun2(arg)
    return arg + 1

被翻译成这个

fun1:
    push 42
    call fun2
    result = pop
    push result
    exit

fun2:
    arg = pop
    arg = arg + 1
    push arg
    exit

TCO可以消除call-pop-push,而是直接跳转到fun2

fun1:
    push 42
    goto fun2
    exit

但是,像你这样的片段是这样的:

fun1:
    push n - 1
    call fun2
    result1 = pop

    push n - 2
    call fun2
    result2 = pop

    result3 = result1 + result2
    push result3
    exit

在这里,不可能用跳转替换调用,因为我们需要返回fun1来执行添加。

免责声明:这是一个相当理论上的解释,我不知道现代JS编译器如何实际实现TCO。 他们非常聪明,所以也许有一种方法来优化这样的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM