2017-08-13 43 views
1

我目前正在瞭解memoization。作爲一個簡單的練習,我用斐波納契實現了記憶。但是,我遇到問題,爲什麼當我不重命名memoized函數時,需要比完成重命名更慢。看看代碼。記憶不按預期工作?

這不能正常工作,並且不能正確緩存。

function memoize(func) { 
    const cache = {}; 

    return function(args) { 
    const cacheKeys = Object.keys(cache).map(el => +el); 
    if (cacheKeys.includes(args)) { 
     return cache[args]; 
    } 
    cache[args] = func(args); 
    return cache[args]; 
    }; 
} 

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

const fibonacci = memoize(wrapped_fibonacci); // <== I do not rename the function. 

for (let i = 1; i <= 40; i++) { 
    console.log(fibonacci(i)); 
} 

但是,當我這樣寫我的代碼。它正常工作並且性能良好

function memoize(func) { 
    const cache = {}; 

    return function(args) { 
    const cacheKeys = Object.keys(cache).map(el => +el); 
    if (cacheKeys.includes(args)) { 
     return cache[args]; 
    } 
    cache[args] = func(args); 
    return cache[args]; 
    }; 
} 

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

fibonacci = memoize(fibonacci); //<== I rename the function 

for (let i = 1; i <= 40; i++) { 
    console.log(fibonacci(i)); 
} 

正如你所看到的。我只是重新分配了函數名稱。 我對Node.js的V8.3.0

第一的結果是這樣做這些測試。

time node fib.js 

real 0m2.413s                          │~                              
user 0m2.400s                          │~                              
sys  0m0.008s 

第二的成績進入這樣

time node fib.js 

real 0m0.263s                          │~                              
user 0m0.252s                          │~                              
sys  0m0.008s 

THATS 1.8S差異

任何人都可以闡明這一些輕?

回答

1

在工作示例,你與memoized函數替換fibonacci也稱爲fibonacci。遞歸調用都採用這種memoized功能,因爲fibonacci-the-originalfibonacci-the-memoized取代。

在非工作例子,你從wrapped_fibonacci創建memoized功能fibonacci,但仍函數調用wrapped_fibonacci,該unmemoized原始遞歸。

如果您還希望更換wrapped_fibonacci,它會再次加速:

const fibonacci = wrapped_fibonacci = memoize(wrapped_fibonacci) 
+0

這使得完美感!謝謝你的恩惠! – Nate