JavaScript模拟map的实现及其性能分析
2014-02-21 11:13
686 查看
JavaScript模拟map的实现极其性能分析
由于JavaScript原生的没有提供Map,而Map又是非常常用的工具类,在这里我为大家介绍几种JavaScript下的Map实现方式。
Map我们需要实现的核心其实就是他的put()和get()方法,至于其他的size()等方法可后续添加。
不了解JavaScript的同学可能首先想到的实现的方式可能会是用一个Array数组来保存数据然后get的时候遍历一遍去匹配Key,因为这是几乎所有语言都通用的方法,简直是跨平台,哈哈。代码和get()的性能我就不列了,相信大家也能知道去遍历一遍数组在数组越来越大的时候性能是直线下降的。遍历100W大小的从后面的例子中大家也可以看一下需要的时间。
下面为大家介绍两种比较合适的方法,
1.使用Object对象,将key作为属性名称保存,get的时候就直接使用属性名称获取值。代码如下。
2.其实和第一种几乎一样,只不过存储的对象从Object改为Array。代码如下。
两种方式实现都很方便,第二种看起来更方便,因为看起来似乎更适合扩展,比如说添加size()方法的时候直接返回数组的大小就可以了。
下面我们对其性能进行一下简单的对比,测试代码:
测试结果:
数据量10000:
数据量100000:
数据量1000000:
结论:
千万数据我的浏览器就崩溃了- -,此数据为chrome下数据,看了一下IE10和FF下表现没有差别,上面的结果key采用的是字符串形式,我曾经也猜测过int型对Array更有利,但是结果表现也是几乎没有差别,两者的get速度都非常的快,几乎可以忽略不计,数据量的改变似乎只是增加了循环初始化数据的时间。
由于JavaScript原生的没有提供Map,而Map又是非常常用的工具类,在这里我为大家介绍几种JavaScript下的Map实现方式。
Map我们需要实现的核心其实就是他的put()和get()方法,至于其他的size()等方法可后续添加。
不了解JavaScript的同学可能首先想到的实现的方式可能会是用一个Array数组来保存数据然后get的时候遍历一遍去匹配Key,因为这是几乎所有语言都通用的方法,简直是跨平台,哈哈。代码和get()的性能我就不列了,相信大家也能知道去遍历一遍数组在数组越来越大的时候性能是直线下降的。遍历100W大小的从后面的例子中大家也可以看一下需要的时间。
下面为大家介绍两种比较合适的方法,
1.使用Object对象,将key作为属性名称保存,get的时候就直接使用属性名称获取值。代码如下。
var Map = function(){ var cache = {}; this.get = function(key){ return cache[key] } this.put = function(key,val){ cache[key] = val; } }; var m = new Map(); m.put('key1','val1'); m.put('key2','val2'); console.log(m.get('key1'));//val1
2.其实和第一种几乎一样,只不过存储的对象从Object改为Array。代码如下。
var Map = function(){ var cache = []; this.get = function(key){ return cache[key] } this.put = function(key,val){ cache[key] = val; } }; var m = new Map(); m.put('key1','val1'); m.put('key2','val2'); console.log(m.get('key2'));//val2
两种方式实现都很方便,第二种看起来更方便,因为看起来似乎更适合扩展,比如说添加size()方法的时候直接返回数组的大小就可以了。
下面我们对其性能进行一下简单的对比,测试代码:
function getCurrentTime() { return new Date().getTime(); } function test(size,Obj){ var d1 = getCurrentTime(); var m = new Obj(); for (var i = 0; i < size; i++) { m.put('key' + i, 'val' + i); } var d2 = getCurrentTime(); var data = m.get('key100'); var d3 = getCurrentTime(); return { t1:d2-d1,//初始化所需时间 t2:d3-d2//get数据所需时间 } } function doTest(){ var dataSize = 1000000;//Map中数据数量 var testTimes = 10;//测试次数 var arrayMapRs = { totalInitTime:0, totalGetTime:0}; var objectMapRs = { totalInitTime:0, totalGetTime:0}; for(var i=0;i<testTimes;i++){ var ta = test(dataSize,ArrayMap); var to = test(dataSize,ObjectMap); arrayMapRs.totalInitTime = arrayMapRs.totalInitTime + ta.t1; arrayMapRs.totalGetTime = arrayMapRs.totalGetTime + ta.t2; objectMapRs.totalInitTime = objectMapRs.totalInitTime + to.t1; objectMapRs.totalGetTime = objectMapRs.totalGetTime + to.t2; } console.info('ArrayMap:'); console.info('初始化Map平均时间:'+arrayMapRs.totalInitTime/testTimes+'ms'); console.info('get平均时间:'+arrayMapRs.totalGetTime/testTimes+'ms'); console.info('ObjectMap:'); console.info('初始化Map平均时间:'+objectMapRs.totalInitTime/testTimes+'ms'); console.info('get平均时间:'+objectMapRs.totalGetTime/testTimes+'ms'); }
测试结果:
数据量10000:
数据量100000:
数据量1000000:
结论:
千万数据我的浏览器就崩溃了- -,此数据为chrome下数据,看了一下IE10和FF下表现没有差别,上面的结果key采用的是字符串形式,我曾经也猜测过int型对Array更有利,但是结果表现也是几乎没有差别,两者的get速度都非常的快,几乎可以忽略不计,数据量的改变似乎只是增加了循环初始化数据的时间。
相关文章推荐
- jsp设置MIME类型
- (function(){...}())javascript中为何在匿名function函数后面还外加一个括号
- js的函数返回值
- 用js实现1-100组成的随机数组
- Extjs 示例简介
- js 相同内容单元格合并
- json格式
- 学习Javascript闭包(Closure)
- JSoup获取指定页面指定URL
- Progress.js – 为页面上的任意对象创建进度条效果
- js数字小写金额转中文大写
- Extjs的组件介绍
- js阿拉伯数字转中文汉字小写 支持到12位
- 关于手动书写json 格式
- js 删除数组的几种方法小结
- headroom.js插件使用方法
- 学习Javascript闭包(Closure)
- extjs 学习笔记
- jsp el
- jstl if条件判断字符串代码