簡體   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