javascript高级知识点——memoization
memoization是一种非常有用的优化技术,它缓存特定输入产生的相应结果。这样麻烦的查找和迭代计算可以尽可能的减少。
它基本的思想是针对特定的输入,已经计算过的结果都是通过缓存当中的数据直接返回而不是经过重复的计算。
实现记忆函数
我们可以简单的将memoization理解为记忆函数经过特定输入产生的结果。
下面是一种基本简单且实用的实现方法,可以很清晰的显示记忆函数的结构
function memoize( fn ) {
return function () {
// 将参数转为数组
var args = Array.prototype.slice.call(arguments);
// 创建缓存对象在目标函数对象里
fn.cache = fn.cache || {};
// 如果缓存当中有相应的结果直接从缓存中返回,否则重新计算并存储缓存对象
return args in fn.cache ? fn.cache[args] : fn.cache[args] = fn.apply(this, args);
};
}
为了方便我们可以更形象的理解记忆函数,我们将上面的三目运算符改成if语句,并添加log。
function memoize( fn ) {
return function () {
// 将参数转为数组
var args = Array.prototype.slice.call(arguments);
// 创建缓存对象在目标函数对象里
fn.cache = fn.cache || {};
// 如果缓存当中有相应的结果直接从缓存中返回,否则重新计算并存储缓存对象
var results;
if (args in fn.cache) {
console.log('返回结果来自于缓存:');
results = fn.cache[args];
}else {
console.log('返回结果来自于函数计算:');
results = fn.cache[args] = fn.apply(this, args);
}
return results
};
}
实际使用
这里我们将其运用到实际中去,下面是一个计算最大公约数的函数。但它不是学习的要点,我们只要知道它接收两个数字,并返回他们的最大公约数。
// 这是一个计算最大公约数的函数
function gcd(a ,b){
var t;
if (a < b) t = b, b = a, a = t;
while(b != 0) t=b, b= a%b, a=t;
return a;
} var cachedGcd = memoize(gcd); console.log(cachedGcd(85, 187)); // 返回结果来自于函数计算: 17 console.log(cachedGcd(85, 187)); // 返回结果来自于缓存:
在上面这段代码,可以看到经memoize处理过的gcd函数便具备记忆缓存的作用。不只是gcd,对于任何特定输入产生特定结果的函数都可以使用记忆函数。
简单测试
使用time简单的测试一下非记忆时,和记忆时函数调用的时间。在不同的浏览器有不同的结果,但是,整体来看记忆时的时间是比非记忆时要短的。
console.time('non-memoized')
cachedGcd(85,187);
console.timeEnd('non-memoized')
console.time('memoized')
cachedGcd(85,187);
console.timeEnd('memoized')
由于gcd函数涉及的运算相对比较少,这还不能很明显的体现记忆函数的优势,试想一下,如果一个函数运算量很大很大。那么通过缓存返回的结果将直接跳过这些复杂的运算,迅速返回结果。
javascript高级知识点——memoization的更多相关文章
- JavaScript高级知识点整理
一.JS中的数组 1.数组的三种定义方式 (1).实例化对象 var aArray=new Array(1,2,3,4,5); (2).快捷创建 var aTwoArray = [1,2,3,&quo ...
- javascript高级知识点——闭包
代码信息来自于http://ejohn.org/apps/learn/. 先给出一个权威的定义,函数对象可以通过作用域相互关联起来,函数体内的变量可以保存在函数的作用域内,这种特性称为闭包. 在闭包内 ...
- javascript高级知识点——函数的长度
代码信息来自于http://ejohn.org/apps/learn/. 函数的长度属性如何工作? function makeNinja(name){} function makeSamurai(na ...
- javascript高级知识点——指定上下文实现
代码信息来自于http://ejohn.org/apps/learn/. 当我们将一个对象的点击事件绑定到一个事件触发元素时会发生什么? <ul id="results"&g ...
- javascript高级知识点——内置对象原型
代码信息来自于http://ejohn.org/apps/learn/. 可以修改内置对象的方法. if (!Array.prototype.forEach) { Array.prototype.fo ...
- javascript高级知识点——继承
代码信息来自于http://ejohn.org/apps/learn/. 继承是如何工作的 function Person(){} function Ninja(){} Ninja.prototype ...
- javascript高级知识点——实例类型
代码信息来自于http://ejohn.org/apps/learn/. 分析一下对象的结构 function Ninja(){} var ninja = new Ninja(); console.l ...
- javascript高级知识点——函数原型
代码信息来自于http://ejohn.org/apps/learn/. 向函数的原型中添加方法 function Ninja(){} Ninja.prototype.swingSword = fun ...
- javascript高级知识点——临时作用域
代码信息来自于http://ejohn.org/apps/learn/. 自执行,临时,函数 (function(){ var count = 0; })(); 这是一个简单的自执行匿名函数. 做一个 ...
随机推荐
- NET基础课--开发工具实用功能
1.浏览代码结构 类视图 2.重构功能 提取长的的方法体中的部分方法到单独函数中 路径:选择代码段,右击重构----提取方法 3.代码结构 a 代码对齐 点[编辑]-[高级]-[设置选定内容的格式] ...
- XMLHttpResponse 在项目里面的运用
前些天在项目里面遇到了一个问题,项目的列表页面每条记录后面都有按钮做审核操作,但是这个操作并不需要引起弹窗,只需要到后台修改一下这条记录的一些状态值,但是操作执行之后却没有刷新页面,只有重新载入或者刷 ...
- jquery selector
jquery的选择器功能 1 :lt(index) selector 一组元素选择index之前的元素,若index<0 则倒着选过来 http://api.jquery.com/lt-sele ...
- CSS基础笔记
之前没有开通好博客,笔记都记录在有道云,今天全部转过来!!! 1.当同一个html元素不止一个样式定义时,内联样式(在html元素内部)拥有最高的优先权:其他如内部样式表(位于<head> ...
- IT定理:摩尔定理,安迪-比尔定理,反摩尔定理
前两天在网上不经意间搜到了一本吴军的<浪潮之巅>,讲的是现代国际上计算机界的各大公司的兴衰沉浮,包括AT&T公司与IBM等等,把它当作IT历史书看,到现在已经看了一部分了.其中,我 ...
- struts2中的action访问web对象
Struts2的Action就是一个普通的POJO对象,它和Web对象request.response.session和application没有耦合在一起,这样便于单独测试Action,那么我们在A ...
- [原创]VS2010中创建动态链接库及其调用
[原创]VS2010中创建动态链接库及其调用 一.创建动态链接库 在VS2010中创建动态链接库的步骤如下: 1)生成->编译->生成MyDll 二.调用 当调用DLL中的方法,程序编译产 ...
- tp中u方法的使用
自学的时候都没怎么使用过该方法,现在刚进入一个新公司参加项目.发现这个方法用的很多,所以记录下来防止以后忘了. U方法用于完成对URL地址的组装,特点在于可以自动根据当前的URL模式和设置生成对应的U ...
- flash播放器遮挡页面中元素问题解决
今天在做一个包含Flash播放器的页面弹出效果时发现Flash播放器总是跑到页面最上层,发现这个问题与Flash的”wmode”属性有关,至于该元素详细此处不做记录,解决办法如下: IE:加入参数:& ...
- ubuntu studio
相对于普通的的Ubuntu Linux而言,Ubuntu Studio更适合于多媒体设计人员,也就是说Ubuntu Studio更适合经常搞图片和电脑音乐的Linux爱好者们. Ubuntu Stud ...