面試 尾呼叫優化

2021-09-25 10:38:00 字數 1756 閱讀 4543

場景

今天去面試futu, 被問到一題 -> 引數為數字, 輸出斐波那契數列對應結果, 實現了一下

function

fibonacci

(n)

然後面試官問: "你覺得這個有什麼問題 ?"

我: "(⊙o⊙)…忘記判斷引數型別了."

面試官: "不是這個問題."

我: "嗯..嗯...嗯.呃...這個..."

面試官: "如果數字很大會怎麼樣?"

我: "會...效能很差"

面試官: "嗯, 會**, 為什麼? 那怎麼改?"

我: "嗯..嗯...嗯.呃...不會..."

面試官: "你回去查一下吧."

game over

回來查原來 有個概念叫尾呼叫優化, 果然還是太菜

什麼是尾呼叫

尾呼叫的概念非常簡單,一句話就能說清楚,就是指某個函式的最後一步是呼叫另乙個函式。尾呼叫-阮一峰

尾呼叫之所以與其他呼叫不同,就在於它的特殊的呼叫位置。

我們知道,函式呼叫會在記憶體形成乙個"呼叫記錄",又稱"呼叫幀"(call frame),儲存呼叫位置和內部變數等資訊。如果在函式a的內部呼叫函式b,那麼在a的呼叫記錄上方,還會形成乙個b的呼叫記錄。等到b執行結束,將結果返回到a,b的呼叫記錄才會消失。如果函式b內部還呼叫函式c,那就還有乙個c的呼叫記錄棧,以此類推。所有的呼叫記錄,就形成乙個"呼叫棧"(call stack)。

遞迴的計算過程(recursive process)包含了兩個階段,先逐級擴充套件(expansion),構造起乙個由被推遲的操作組成的鏈條(會被直譯器儲存在堆疊裡),然後在收縮(contraction)階段逐級回溯執行那些操作。隨著遞迴計算步驟的增多,這種方法消耗的資源會越來越大,而且會包含越來越多的冗餘操作,上面那個求斐波那契數列的例子(在sicp裡被稱作「樹形遞迴」)在這方面問題尤其嚴重,因為它的計算步驟會隨著引數而指數性的增長。

尾呼叫由於是函式的最後一步操作,所以不需要保留外層函式的呼叫記錄,因為呼叫位置、內部變數等資訊都不會再用到了,只要直接用內層函式的呼叫記錄,取代外層函式的呼叫記錄就可以了。

優化->尾呼叫
function

lastfibonacci

(n, acc1, acc2)

lastfibonacci(6

,1,1

)//8

lastfibonacci(7

,1,1

)//13

這樣每次都要輸入1,1,可以用柯里化或es6

加柯里化或es6

// 再封裝一層柯里化-----------

function

curringf

(acc1, acc2)

}let func =

curringf(1

,1)func(6

)// 8

func(7

)// 13

//或 es6---------

function

lastfibonacci

(n, acc1=

1, acc2=1)

lastfibonacci(7

)//13

啊啊啊啊啊啊啊啊啊啊啊

尾呼叫優化

尾呼叫 tail call 是函式式程式設計的乙個重要概念,本文介紹它的含義和用法。一 什麼是尾呼叫?尾呼叫的概念非常簡單,一句話就能說清楚,就是指某個函式的最後一步是呼叫另乙個函式。function f x 上面 中,函式f的最後一步是呼叫函式g,這就叫尾呼叫。以下兩種情況,都不屬於尾呼叫。情況一...

尾呼叫優化

本文 日期 2015年4月10日 尾呼叫 tail call 是函式式程式設計的乙個重要概念,本文介紹它的含義和用法。尾呼叫的概念非常簡單,一句話就能說清楚,就是指某個函式的最後一步是呼叫另乙個函式。function f x 上面 中,函式f的最後一步是呼叫函式g,這就叫尾呼叫。以下兩種情況,都不屬...

尾呼叫優化

尾呼叫的概念非常簡單,一句話就能說清楚,就是指某個函式的最後一步是呼叫另乙個函式。function f x 上面 中,函式f的最後一步是呼叫函式g,這就叫尾呼叫。以下兩種情況,都不屬於尾呼叫。情況一 function f x 情況二 function f x 上面 中,情況一是呼叫函式g之後,還有別...