js Map 原理
这段话是我抄的 感觉不太对
众所周知 map 是个hash 表,但js的map 不是,js的map很烂,是两个数组组成的,Map api共用了两个数组(一个存放key,一个存放value)。给Map set值时会同时将key和value添加到这两个数组的末尾。从而使得key和value的索引在两个数组中相对应。当从Map取值时,需要遍历所有的key,然后使用索引从存储值的数组中检索出相应的value。这个实现的缺点很大,首先是赋值和搜索的时间复杂度为O(n),其次是可能导致内存溢出,因为数组会一直保存每个键值引用,即便是引用早已离开作用域,垃圾回收器也无法回收这些内存。
测试 Map 和 Object的效率
MAP
let map = new Map()
let person = {name:'gromy',age:0}
let sum = 100000
let start = Date.now()
for(let i = 0;i<sum;i++){
let k = person.name+i
let val = Object.assign({},person)
val.age = i
map.set(k,val)
}
console.log('add',Date.now() - start)
setTimeout(()=>{
let start = Date.now()
for(let i = 0;i<sum;i++){
let k = person.name+i
map.get(k)
}
console.log('get',Date.now() - start)
},200)
setTimeout(()=>{
let start = Date.now()
map.forEach((k,v)=>{})
console.log('forEach',Date.now() - start)
},400)
add
let start = Date.now()
for(let i = 0;i<10000;i++){
let k = person.name+i
let val = Object.assign({},person)
val.age = i
map.set(k,val)
}
console.log(Date.now() - start)
增大为100000
for(let i = 0;i<100000;i++){
let k = person.name+i
let val = Object.assign({},person)
val.age = i
map.set(k,val)
}
get
setTimeout(()=>{
let start = Date.now()
for(let i = 0;i<sum;i++){
let k = person.name+i
map.get(k)
}
console.log(Date.now() - start)let start1 = Date.now()
let val = map.get('gromy9999')
console.log(Date.now() - start1,val)
遍历
一起执行一下
这里第一次事件循环结束注册 两个 timeout 事件,还没执行
结论
set 的时候占用内存,get也会占用内存,遍历不会(heap)
时间
Object
let obj = {}
let person = {name:'gromy',age:0}
let sum = 100000
let start = Date.now()
for(let i = 0;i<sum;i++){
let k = person.name+i
let val = Object.assign({},person)
val.age = i
obj[k]=val
}
console.log('add',Date.now() - start)
setTimeout(()=>{
let start = Date.now()
for(let i = 0;i<sum;i++){
let k = person.name+i
obj[k]
}
console.log('get',Date.now() - start)
},200)
setTimeout(()=>{
let start = Date.now()
for(k in obj){
obj[k]
}
console.log('forEach',Date.now() - start)
},400)
结论
内存:Map > Object
时间:Object > Map
map
object
10s 左右被释放
weakMap
let wm = new WeakMap()
let person = { name: 'gromy', age: 0 }
let sum = 100000
setTimeout(() => {
let start = Date.now()
for (let i = 0; i < sum; i++) {
let val = Object.assign({}, person)
val.age = i
wm.set(val, val)
}
console.log('add', Date.now() - start)
}, 1000)
setTimeout(() => {
let start = Date.now()
for (let i = 0; i < sum; i++) {
let val = Object.assign({}, person)
val.age = i
wm.get(val)
}
console.log('get', Date.now() - start)
}, 2000)
一样被释放了
所以 weakMap的优势?
看下时间,
跟Map 一样