JavaScript中Memoization的用法介绍(代码)

如果下载的源码需要作者授权,请更换源码。本站免费分享资源不会增加授权

本篇文章给大家带来的内容是关于JavaScript中Memoization的用法介绍(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

memoization 来源于拉丁语 memorandum (“to be remembered”),不要与 memorization 混淆了。

首先来看一下维基百科的描述:

In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.

简单来说,memoization 是一种优化技术,主要用于通过存储昂贵的函数调用的结果来加速计算机程序,并在再次发生相同的输入时返回缓存的结果。

本文首先介绍一个简单的使用 memoization 优化技术的例子,然后解读 underscore 和 reselect 库中使用 memoization 的源码,加深理解。

阶乘

不使用 memoization

不假思索,我们会立即写下如下的代码:

const factorial = n => {     if (n === 1) {         return 1     } else {         return factorial(n - 1) * n     } };

使用 memoization

const cache = [] const factorial = n => {     if (n === 1) {         return 1     } else if (cache[n - 1]) {         return cache[n - 1]     } else {         let result = factorial(n - 1) * n         cache[n - 1] = result         return result     } };

使用 闭包 和 memoization

常见的方式是 闭包 和 memoization 一起搭配使用:

const factorialMemo = () => {     const cache = []     const factorial = n => {         if (n === 1) {             return 1         } else if (cache[n - 1]) {             console.log(`get factorial(${n}) from cache...`)             return cache[n - 1]         } else {             let result = factorial(n - 1) * n             cache[n - 1] = result             return result         }     }     return factorial }; const factorial = factorialMemo();

继续变形,下面这种编写方式是最常见的形式。

const factorialMemo = func => {     const cache = []     return function(n) {         if (cache[n - 1]) {             console.log(`get factorial(${n}) from cache...`)             return cache[n - 1]         } else {             const result = func.apply(null, arguments)             cache[n - 1] = result             return result         }     } }  const factorial = factorialMemo(function(n) {     return n === 1 ? 1 : factorial(n - 1) * n });

从阶乘的这个例子可以知道 memoization 是一个空间换时间的方式,存储执行结果,下次再次发生相同的输入会直接输出结果,提高了执行的速度。

underscore 源码中的 memoization

// Memoize an expensive function by storing its results. _.memoize = function(func, hasher) {     var memoize = function(key) {         var cache = memoize.cache;         var address = '' + (hasher ? hasher.apply(this, arguments) : key);         if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);         return cache[address];     };     memoize.cache = {};     return memoize; };

代码一目了然,使用 _.memoize 来实现阶乘如下:

const factorial = _.memoize(function(n) {     return n === 1 ? 1 : factorial(n - 1) * n });

参照这个源码,上面的阶乘继续可以变形如下:

const factorialMemo = func => {     const memoize = function(n) {         const cache = memoize.cache         if (cache[n - 1]) {             console.log(`get factorial(${n}) from cache...`)             return cache[n - 1]         } else {             const result = func.apply(null, arguments)             cache[n - 1] = result             return result         }     }     memoize.cache = []     return memoize }  const factorial = factorialMemo(function(n) {     return n === 1 ? 1 : factorial(n - 1) * n });

reselect 源码中的 memoization

export function defaultMemoize(func, equalityCheck = defaultEqualityCheck) {     let lastArgs = null     let lastResult = null     // we reference arguments instead of spreading them for performance reasons     return function () {         if (!areArgumentsShallowlyEqual(equalityCheck, lastArgs, arguments)) {             // apply arguments instead of spreading for performance.             lastResult = func.apply(null, arguments)         }          lastArgs = arguments         return lastResult     } };

从源码可以知道当 lastArgs 与 arguments 相同的时候,就不会再执行 func。

总结

memoization 是一种优化技术,避免一些不必要的重复计算,可以提高计算速度。

本文由(壳先生)整理自网络,如转载请注明出处:https://www.mrshell.com;
本站发布的内容若侵犯到您的权益,请邮件联系 i@mrshell.com 删除,我们将及时处理!
===========================================================================

1. 本站大部分下载资源收集于网络,不保证其完整性以及安全性,请下载后自行测试。
2. 本站资源仅供学习和交流使用,版权归资源原作者所有,请在下载后24小时之内自觉删除。
3. 不得使用于非法商业用途,商用请支持正版!不得违反国家法律,否则后果自负!
4. 若作商业用途,请购买正版,由于未及时购买和付费发生的侵权行为,与本站无关。
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!

=================================================================

壳先生 » JavaScript中Memoization的用法介绍(代码)

发表评论

提供最优质的资源集合

立即查看 了解详情