Javascript 解释实现一个记忆化辅助函数
什么是记忆化?
记忆化是一种编程技术,通过存储函数已经计算过的值来提高函数的效率。
它通过缓存函数调用的结果来提高程序效率。我们经常会浪费时间用相同的参数再次调用函数,而这些参数已经计算过了。所以我们可以存储已计算的值,这样当函数使用相同的参数调用时,我们只需要返回缓存的值。
示例 1: 在这个示例中,我们将看到记忆化的工作原理:
Javascript
<script>
function mul(num1, num2) {
for (let i = 0; i < 10000000; i++) {
}
return num1 * num2;
}
console.log(mul(2, 3));
console.log(mul(2, 3));
</script>
输出:
6
6
解释: 在这个示例中,我们计算了两个数字的乘积,但是由于for循环,函数需要花费一些时间。而且我们一遍又一遍地用相同的参数调用这个函数。这是时间的浪费,因为我们已经计算出了mul(2,3)的结果,而我们又用相同的参数再次调用它。
所以,在这种情况下,我们可以使用 记忆化技术 来存储mul(2,3)的值,当我们再次用相同的参数调用该函数时,我们将返回缓存的值。
示例2: 让我们看一下我们的函数计算mul(2,3)的时间。
JavaScript
<script>
function mul(num1, num2) {
for (let i = 0; i < 10000000; i++) {
}
return num1 * num2;
}
console.time("Time taken");
console.log(mul(2, 3));
console.timeEnd("Time taken");
</script>
输出:
6
Time taken: 14.60ms
这个函数花了 14.60毫秒 来计算(2,3)的乘积
通过记忆化技术,我们可以增加函数的效率,通过存储函数已经计算过的值,这样当我们再次用相同的参数调用函数时,只需返回缓存的值。
示例3: 现在让我们看下如何使用记忆化技术来减少重复执行函数所需的时间。
Javascript
<script>
function memoizeFunction(func) {
let obj = {};
return function (a, b) {
const x = a.toString() + b.toString();
if (!obj[x]) {
obj[x] = func(a, b);
}
return obj[x];
}
}
function mul(num1, num2) {
for (let i = 0; i < 10000000; i++) {
}
return num1 * num2;
}
console.time("First time time taken");
let func = memoizeFunction(mul);
console.log(func(2, 3));
console.timeEnd("First time time taken");
console.time("Second time time taken");
func = memoizeFunction(mul);
console.log(func(2, 3));
console.timeEnd("Second time time taken");
console.time("Third time time taken");
func = memoizeFunction(mul);
console.log(func(2, 3));
console.timeEnd("Third time time taken");
</script>
输出:
6
First time, time taken: 24.73ms
6
Second time, time taken:22,17ms
6
Third time, time taken:8.30ms
注意: **** 完成任务所需的时间可能会有所变化。
解释: 在这种情况下,我们使用了记忆化函数来缓存我们已经计算过的值。当我们第一次调用func(2,3)时,它会将参数转换为字符串形式,然后将其存储在obj对象中,并计算出对应的值。
当我们再次使用相同的参数调用func时,首先它会检查它是否已经存在于 对象obj 中。如果已经存在,则不会重新计算,而是直接返回存储在 对象obj 中的值。
从输出中可以看出,每次使用相同的参数调用函数计算2和3的乘积所需的时间都减少了。
每次所需的时间:
24.73 ms
22.17 ms
8.30 ms
从输出结果可以清楚地看出,记忆化技术在每次反复调用具有相同参数的函数时帮助减少了时间。
示例4: 我们来看另一个在计算 斐波那契数 时使用记忆化技术的示例。
Javascript
<script>
function memoizeFunction(func) {
let obj = {};
return function (a) {
const x = a.toString();
if (!obj[x]) {
obj[x] = func(a);
}
return obj[x];
}
}
function fibonacci(n) {
if (n === 0 || n === 1)
return n;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
console.time("First time, time taken");
let func = memoizeFunction(fibonacci);
console.log(func(10));
console.timeEnd("First time, time taken");
console.time("Second time, time taken");
func = memoizeFunction(fibonacci);
console.log(func(10));
console.timeEnd("Second time, time taken");
console.time("Third time, time taken");
func = memoizeFunction(fibonacci);
console.log(func(10));
console.timeEnd("Third time, time taken");
</script>
输出:
55
First time, time taken: 0.62ms
55
Second time, time taken: 0.28ms
55
Third time, time taken: 0.20ms
优点:
- 借助记忆化,我们不需要重复计算数值
- 当我们反复使用相同参数调用函数时,它有助于减少执行函数所需的时间
- 它提高了性能
缺点:
- 它使用内存来加速函数的执行
- 它给程序增加了额外的负担
- 空间开销
极客教程