简体   繁体   English

JavaScript中的尾递归优化

[英]Tail recursion optimization in JavaScript

JavaScript will only optimize into a non-recursive loop a recursive step if it is the last expression in a block (IIUC). 如果它是块(IIUC)中的最后一个表达式,JavaScript将仅优化为非递归循环的递归步骤。 Does that mean that the right-hand recursive call will be optimised and the left-hand recursive call will NOT in the following? 这是否意味着右手递归调用将被优化,左手递归调用将不会在下面?

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

Does that mean that the right-hand recursive call will be optimised and the left-hand recursive call will NOT in the following? 这是否意味着右手递归调用将被优化,左手递归调用将不会在下面?

I don't think so. 我不这么认为。 TCO is only possible when you directly return what other function returns. 只有在您直接返回其他函数返回的内容时才可以使用TCO。 Since your function processes both results before returning them, neither of the calls can be tail-optimized. 由于您的函数在返回结果之前处理两个结果,因此这两个调用都不能进行尾部优化。

Low-level explanation 低级别的解释

In terms of a stack-based machine, a code like this: 就基于堆栈的机器而言,代码如下:

function fun1()
   return fun2(42)

function fun2(arg)
    return arg + 1

is translated to this 被翻译成这个

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

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

TCO can eliminate call-pop-push and instead jump to fun2 directly: TCO可以消除call-pop-push,而是直接跳转到fun2

fun1:
    push 42
    goto fun2
    exit

However, a snippet like yours would be this: 但是,像你这样的片段是这样的:

fun1:
    push n - 1
    call fun2
    result1 = pop

    push n - 2
    call fun2
    result2 = pop

    result3 = result1 + result2
    push result3
    exit

Here, it's not possible to replace calls with jumps, because we need to return back to fun1 to perform the addition. 在这里,不可能用跳转替换调用,因为我们需要返回fun1来执行添加。

Disclaimer: this is a rather theoretical explanation, I have no idea how modern JS compilers actually implement TCO. 免责声明:这是一个相当理论上的解释,我不知道现代JS编译器如何实际实现TCO。 They are quite smart, so perhaps there's a way to optimize stuff like this as well. 他们非常聪明,所以也许有一种方法来优化这样的东西。

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

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