您的位置:首页 > Web前端 > JavaScript

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的时候就直接使用属性名称获取值。代码如下。

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速度都非常的快,几乎可以忽略不计,数据量的改变似乎只是增加了循环初始化数据的时间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: