JavaScript API性能对比系列一:Map,Set,数组,对象性能对比

以下是测试性能的环境

CPUAMD Ryzen 9 5900HX with Radeon Graphics 八核
操作系统Windows 11 家庭中文版 (64位)
内存16GB(3200 MHz / 3200 MHz)
Nodejsv18.16.0

测试一:循环赋值

Array

const arr = [];

console.time('数组')
for (let i = 0; i < time; i++) {
    arr.push(i);
}
console.timeEnd('数组')

Set

const set = new Set();
console.time('set')
for (let i = 0; i < time; i++) {
    set.add(i);
}
console.timeEnd('set')

Map

const map = new Map();
console.time('map')
for (let i = 0; i < time; i++) {
    map.set(i, undefined);
}
console.timeEnd('map')

Object

const obj = {};
console.time('对象')
for (let i = 0; i < time; i++) {
    obj[i] = undefined;
}
console.timeEnd('对象')

测试结果

数组和对象的插入速度很快。

Nodejs

类型1万次10万次100万次1000万次
数组0.4ms4ms20ms210ms
Set0.7ms6ms72ms2.2s
对象0.26ms3ms23ms592ms
Map1.24ms7ms110ms2.7s

测试二:数组赋值

Set

const setArr = [];
for (let i = 0; i < time; i++) {
    setArr.push(i);
}
console.time('set')
const set = new Set(setArr);
console.timeEnd('set')

Map

const mapArr = [];
for (let i = 0; i < time; i++) {
    mapArr.push([i, undefined]);
}
console.time('map')
const map = new Map(mapArr);
console.timeEnd('map')

测试结果

Nodejs

类型1万次10万次100万次1000万次
Set0.7ms6ms89ms2.4s
Map0.59ms7ms152ms3.5s

测试三:循环遍历

 Array

console.time('数组 forEach')
arr.forEach(val => {});
console.timeEnd('数组 forEach')

console.time('数组 for...in')
for (let i in arr) {
    arr[i];
}
console.timeEnd('数组 for...in')

console.time('数组 for...of')
for (let val of arr) {}
console.timeEnd('数组 for...of')

console.time('数组 for')
const length = arr.length;
for (let i; i < length; i++) {
    arr[i];
}
console.timeEnd('数组 for')

Set

console.time('set forEach')
set.forEach(val => {});
console.timeEnd('set forEach')

console.time('set for...of')
for (let val of set) {}
console.timeEnd('set for...of')

Map

console.time('map forEach')
map.forEach((val, key) => {});
console.timeEnd('map forEach')

console.time('map for...of')
for (let val of map) {}
console.timeEnd('map for...of')

Object

console.time('对象 forEach')
Object.keys(obj).forEach((key) => {})
console.timeEnd('对象 forEach')

console.time('对象 for...in')
for (let key in obj) {
    obj[key]
}
console.timeEnd('对象 for...in')

测试结果

数组的普通for循环在大数据量的情况下速度非常快,比forEach快了太多了。

普通对象的遍历性能非常低(虽然在插入数据的时候要比Map和Set快),如果要对哈希表数据结构做遍历操作,还是建议使用Map或Set。

Nodejs

类型方法1万次10万次100万次1000万次
数组forEach0.107ms1.054ms5.598ms50.962ms
for...in0.762ms6.372ms103.741ms1.369s
for...of0.614ms3.906ms28.793ms97.9ms
for0.104ms1.251ms3.016ms7.216ms
SetforEach0.102ms0.922ms5.537ms43.978ms
for...of0.167ms3.458ms8.406ms57.894ms
MapforEach0.104ms0.867ms5.886ms47.26ms
for...of0.461ms3.486ms17.414ms133.956ms
对象forEach0.206ms5.356ms87.389ms1.612s
for...in0.424ms7.009ms98.209ms1.921s

测试四:随机查询

Array

console.time('数组')
for (let i = 0; i < time; i++) {
    const tmp = arr[i];
}
console.timeEnd('数组')

Map

console.time('map')
for (let i = 0; i < time; i++) {
    const tmp = map.get(i);
}
console.timeEnd('map')

Object

console.time('对象')
for (let i = 0; i < time; i++) {
    const tmp = obj[i];
}
console.timeEnd('对象')

测试结果

Nodejs

类型1万次10万次100万次1000万次
数组0.263ms1.12ms1.633ms5.835ms
对象0.141ms1.113ms1.392ms5.425ms
Map0.43ms4.434ms41.235ms455.84ms

测试五:判断数据存不存在

Array

console.time('数组')
for (let i = 0; i < time; i++) {
    if (arr[i]) {}
}
console.timeEnd('数组')

Map

console.time('对象')
for (let i = 0; i < time; i++) {
    if (obj[i]) {}
}
console.timeEnd('对象')

Set

console.time('set')
for (let i = 0; i < time; i++) {
    if(set.has(i)) {}
}
console.timeEnd('set')

Object

console.time('map')
for (let i = 0; i < time; i++) {
    if(map.has(i)) {}
}
console.timeEnd('map')

测试结果

Nodejs

类型1万次10万次100万次1000万次
数组0.241ms1.119ms1.666ms5.662ms
对象0.141ms1.161ms1.693ms5.785ms
Set0.325ms4.785ms51.14ms803.376ms
Map0.354ms4.835ms48.093ms449.937ms

测试五:随机删除

Array

console.time('数组')
for (let i = 0; i < time; i++) {
    arr.splice(i, 1);
}
console.timeEnd('数组')

Map

console.time('对象')
for (let i = 0; i < time; i++) {
   delete obj[i];
}
console.timeEnd('对象')

Set

console.time('set')
for (let i = 0; i < time; i++) {
    set.delete(i);
}
console.timeEnd('set')

Object

console.time('map')
for (let i = 0; i < time; i++) {
    map.delete(i)
}
console.timeEnd('map')

测试结果

数组是从后往前删的,严格意义讲不算随即删除,后续会单独补充CASE测试一下

Nodejs

类型1万次10万次100万次1000万次
数组1.368ms5.185ms35.957ms255.075ms
对象0.773ms5.272ms48.731ms421.327ms
Set0.78ms7.587ms97.004ms1.734s
Map0.914ms9.43ms113.456ms1.930s

测试六:指定size和不指定size的区别

const time = 10000 * 1000;
const randomArr = [];
for (let i = 0; i < time; i++) {
    randomArr.push(Math.random() * time >> 0);
}

console.time('数组,不指定size, push')
const arr = [];
for (let i = 0; i < time; i++) {
    arr.push(i);
}
console.timeEnd('数组,不指定size, push')

console.time('数组,不指定size, shift')
const arr1 = [];
for (let i = 0; i < time; i++) {
    arr1.unshift(i);
}
console.timeEnd('数组,不指定size, shift')

console.time('数组,不指定size, 正序')
const arr2 = [];
for (let i = 0; i < time; i++) {
    arr2[i] = 0;
}
console.timeEnd('数组,不指定size, 正序')

console.time('数组,不指定size, 倒序')
const arr3 = [];
for (let i = time - 1; i >= 0; i--) {
    arr3[i] = i;
}
console.timeEnd('数组,不指定size, 倒序')

console.time('数组,不指定size, 随机')
const arr4 = [];
for (let i = time - 1; i >= 0; i--) {

    arr4[randomArr[i]] = i;
}
console.timeEnd('数组,不指定size, 随机')

console.time('数组,指定size,正序')
const arr5 = new Array(time);
for (let i = 0; i < time; i++) {
    arr5[i] = 0;
}
console.timeEnd('数组,指定size,正序');

console.time('数组,指定size,倒序')
const arr6 = new Array(time);
for (let i = 0; i < time; i++) {
    arr6[i] = 0;
}
console.time('数组,指定size,倒序')

console.time('数组,指定size,随机')
const arr7 = new Array(time);
for (let i = time - 1; i >= 0; i--) {

    arr7[randomArr[i]] = i;
}
console.time('数组,指定size,随机')

console.time('数组,指定size,随机,非稀疏数组')
const arr8 = new Array(time).fill(undefined);
for (let i = time - 1; i >= 0; i--) {

    arr8[randomArr[i]] = i;
}
console.timeEnd('数组,指定size,随机,非稀疏数组')

测试结果

数组是从后往前删的,严格意义讲不算随即删除,后续会单独补充CASE测试一下

Nodejs

类型指定size初始化方法顺序1万次10万次100万次1000万次
数组-
push
正序1.12ms3.534ms18.844ms215.098ms
-unshift倒序7.502ms677.837ms1:08.297 (m:ss.mmm)时间太久放弃
-
随机存储
正序0.74ms4.047ms22.124ms199.869ms
-随机存储倒序0.571ms6.463ms63.207ms1.391s
-随机存储随机1.336ms8.192ms85.356ms1.881s
随机存储正序0.526ms4.254ms5.39ms60.065ms
随机存储倒序0.171ms5.827ms5.513ms45.6ms
随机存储随机0.241ms2.449ms10.456ms182.37ms
随机存储随机0.277ms1.917ms8.862ms168.578ms
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值