Memoization is one technique that lets you speed up considerably your applications.
记忆化是一种技术,可让您大大加快应用程序的速度。
It is not a technique unique to JavaScript, although I tagged this post as “JavaScript” because I will provide some JS examples.
这不是JavaScript独有的技术,尽管我将本文标记为“ JavaScript”,因为我将提供一些JS示例。
Memoization is the act of storing the result of a function call after we run it, in the function itself. The next time we call the function, instead of performing its “regular” execution once again, it just returns us the stored result.
记忆化是在函数调用后将其存储在函数本身中的结果。 下次我们调用该函数时,它不会再执行“常规”执行,而只是返回存储的结果。
It’s caching, for functions.
为功能缓存 。
Why is this useful?
为什么这有用?
Suppose our function takes 1 second to run, while caching lets us speed up the process to 2 milliseconds. There is a clear gain here.
假设我们的函数运行需要1秒钟,而缓存则可以使过程加快到2毫秒。 这里有明显的收获。
Sounds pretty cool. Where is the catch?
听起来很酷。 渔获物在哪里?
Memoization works if the result of calling a function with the same set of arguments results in the same output. In other words, the function must be pure. Otherwise caching the result would not make sense.
如果调用具有相同参数集的函数的结果导致相同的输出,则记忆有效。 换句话说,该函数必须是pure 。 否则,缓存结果将毫无意义。
So, database queries, network requests, writing to files and other non-pure operations cannot be optimized with memoization. For those, you will need to find other ways to optimize them. Or just live with their inefficiency, which sometimes is unavoidable.
因此,无法通过备注优化数据库查询,网络请求,写入文件和其他非纯操作。 对于这些,您将需要找到其他方法来对其进行优化。 或者只是生活在低效率的环境中,这有时是不可避免的。
Let’s create one example:
让我们创建一个示例:
// Calculate the factorial of num
const fact = num => {
if (!fact.cache) {
fact.cache = {}
}
if (fact.cache[num] !== undefined) {
console.log(num + ' cached')
return fact.cache[num];
} else {
console.log(num + ' not cached')
}
fact.cache[num] = num === 0 ? 1 : num * fact(num - 1)
return fact.cache[num]
}
calculating the factorial of a number. The first time fact()
is run, it creates a cache
object property on the function itself, where to store the result of its calculation.
计算数字的阶乘。 第一次运行fact()
,它将在函数本身上创建一个cache
对象属性,用于在其中存储其计算结果。
Upon every call, if we don’t find the result of the number in the cache
object, we perform the calculation. Otherwise we just return that.
每次调用时,如果我们在cache
对象中找不到数字的结果,则执行计算。 否则,我们只返回它。
Try to run it. I made a Codepen to make it easy to test, which uses document.write()
to print to the HTML page (first time I used document.write()
in ages, but this time it was useful).
尝试运行它。 我制作了一个Codepen以使其易于测试,它使用document.write()
来打印到HTML页面(我很久以来第一次使用document.write()
,但这一次非常有用)。
See the Pen Memoization example factorial by Flavio Copes (@flaviocopes) on CodePen.
见笔memoization的例子阶乘由弗拉维奥·科佩斯( @flaviocopes上) CodePen 。
There are libraries that will add the memoization feature to any pure function, so you can skip the task of modifying the function itself, but you just decorate it with this functionality.
有一些库可以将备注功能添加到任何纯函数中,因此您可以跳过修改函数本身的任务,而只是使用此功能来装饰它。
In particular I mention fast-memoize.
我特别提到快速记忆 。
Lodash also has a memoize()
method, if you are a Lodash fan.
如果您是Lodash迷,Lodash也有一个memoize()
方法 。