实现 JS 函数记忆
JavaScript 函数记忆是一种优化技术,用于缓存函数的输入和输出结果,以便在以后的调用中重用它们。这可以提高函数的性能,特别是当函数被频繁调用时。
什么是函数记忆?
函数记忆是一种缓存技术,它可以缓存函数的输入和输出结果。
当函数被调用时,它首先检查输入是否已经被缓存。如果已经缓存,则直接返回缓存的输出结果。否则,函数会计算输出结果并将输入和输出结果添加到缓存中,以便以后使用。
函数记忆可以显著提高函数的性能,特别是当函数被频繁调用时。然而,在实际应用中,它可能会增加代码的复杂性和内存占用,因此需要根据具体情况进行权衡。
js
function eq(a, b) {
return Object.is(a, b)
}
function memoize(fn) {
let lastArg
let lastResult
return function (arg) {
if (lastArg !== undefined && eq(lastArg, arg)) {
return lastResult
}
lastArg = arg
lastResult = fn(arg)
return lastResult
}
}
斐波那契数列
这个函数的性能非常低下,因为它会在计算斐波那契数列的每一项时都重新计算前面的项。现在,我们将使用函数记忆来优化它。
js
function fibonacci(n) {
if (n <= 1) {
return n
}
return fibonacci(n - 1) + fibonacci(n - 2)
}
fibonacci(5)
现在,我们将使用函数记忆来优化它。
js
const cache = {}
function fibonacci(n) {
if (n <= 1) return n
if (cache[n]) return cache[n]
const result = fibonacci(n - 1) + fibonacci(n - 2)
cache[n] = result
return result
}
console.log(fibonacci(5)) // 5
console.log(fibonacci(10)) // 55
console.log(fibonacci(15)) // 610
console.log(fibonacci(20)) // 6765
console.log(fibonacci(25)) // 75025
console.log(fibonacci(30)) // 832040
现在多次调用 fibonacci() 函数时,它会直接返回缓存中的结果,而不是每次都重新计算。这可以显著提高函数的性能。需要注意的是,函数记忆不是万能的解决方案。在某些情况下,它可能会增加代码的复杂性和内存占用。因此,我们需要根据具体情况进行权衡。在实际应用中,我们可以使用现有的 JavaScript 库来自动实现函数记忆,例如 memoizee 和 lru-memoize 等