JavaScript 中 Map 和 Object 的选择
最近在阅读 Js 红宝书,读到 Map 和 Object 的选择问题。 这里分享给大家我的学习和总结。
先说结论,增删较多用 Map,查找较多用 Object。
书中详细从 4 个角度比较了两者的差异,这里简要概括一下。
-
内存占比: Map 大约比 Object 多存储 50% 的键值对。
-
插入性能:Map 稍微快一点,如果有大量插入操作,选 Map。
-
查找速度: 如果有大量查找操作,选 Object。(书上写大量数据时 Object 更快,但是测试下来,数据量大时 Map 更快?)
-
删除性能:Map 的 删除比 Map 的插入和查找更快, 选 Map。
接下来,用代码验证一下,这些结论是否为真。
1. 比较内存占比
由于内存占比无法直接测量,所以使用间接的方式大致估算一下内存占用。
//比较内存占比
function measureMemoryUsage(iterations) {
const obj = {};
const map = new Map();
// 填充对象和Map
for (let i = 0; i < iterations; i++) {
obj[`key${i}`] = `value${i}`;
map.set(`key${i}`, `value${i}`);
}
// 序列化对象和Map
const objSerialized = JSON.stringify(obj);
const mapSerialized = Array.from(map, ([key, value]) => `${key}:${value}`).join(',');
// 计算大小并比较
const objSize = new Blob([objSerialized], { type: 'application/json' }).size;
const mapSize = new Blob([mapSerialized], { type: 'application/json' }).size;
console.log(`Object size: ${objSize} bytes`);
console.log(`Map size: ${mapSize} bytes`);
console.log(`Map is approximately ${(mapSize / objSize) * 100}% of the size of Object`);
}
// 测试插入1000个键值对
measureMemoryUsage(1000);
可以看到,这里 Map 占用的内存大概是 Object 的79%。
2. 比较插入性能
function testInsertionPerformance() {
const iterations = 10000; // 测试插入次数
let startTime = performance.now();
for (let i = 0; i < iterations; i++) {
const obj = {};
obj[`key${i}`] = `value${i}`;
}
const objectInsertionTime = performance.now() - startTime;
startTime = performance.now();
for (let i = 0; i < iterations; i++) {
const map = new Map();
map.set(`key${i}`, `value${i}`);
}
const mapInsertionTime = performance.now() - startTime;
console.log(`Object insertion time: ${objectInsertionTime} ms`);
console.log(`Map insertion time: ${mapInsertionTime} ms`);
}
testInsertionPerformance();
插入的速度,Map 明显要比 Object 快。
3.比较查找速度
function testLookupPerformance() {
const map = new Map();
const obj = {};
for (let i = 0; i < 500; i++) {
map.set(`key${i}`, `value${i}`);
obj[`key${i}`] = `value${i}`;
}
let startTime = performance.now();
for (let i = 0; i < 500; i++) {
const value = map.get(`key${i}`);
}
const mapLookupTime = performance.now() - startTime;
startTime = performance.now();
for (let i = 0; i < 500; i++) {
const value = obj[`key${i}`];
}
const objectLookupTime = performance.now() - startTime;
console.log(`Map lookup time: ${mapLookupTime} ms`);
console.log(`Object lookup time: ${objectLookupTime} ms`);
}
testLookupPerformance();
可以看到,当数据较少时,Object 更快。
function testLookupPerformance() {
const map = new Map();
const obj = {};
for (let i = 0; i < 100000; i++) {
map.set(`key${i}`, `value${i}`);
obj[`key${i}`] = `value${i}`;
}
let startTime = performance.now();
for (let i = 0; i < 100000; i++) {
const value = map.get(`key${i}`);
}
const mapLookupTime = performance.now() - startTime;
startTime = performance.now();
for (let i = 0; i < 100000; i++) {
const value = obj[`key${i}`];
}
const objectLookupTime = performance.now() - startTime;
console.log(`Map lookup time: ${mapLookupTime} ms`);
console.log(`Object lookup time: ${objectLookupTime} ms`);
}
testLookupPerformance();
当数据量增大时,Map 就比 Object 快多了。
4.比较删除性能
function testDeletionPerformance() {
const map = new Map();
const obj = {};
for (let i = 0; i < 1000000; i++) {
map.set(`key${i}`, `value${i}`);
obj[`key${i}`] = `value${i}`;
}
let startTime = performance.now();
for (let i = 0; i < 1000000; i++) {
map.delete(`key${i}`);
}
const mapDeletionTime = performance.now() - startTime;
startTime = performance.now();
for (let i = 0; i < 1000000; i++) {
delete obj[`key${i}`];
}
const objectDeletionTime = performance.now() - startTime;
console.log(`Map deletion time: ${mapDeletionTime} ms`);
console.log(`Object deletion time: ${objectDeletionTime} ms`);
}
testDeletionPerformance();
当数据量较少时,区别还不明显,当增大到 100 万时,很明显是 Map 胜出。
查找速度仍有疑问,因为测试和书中不一致,问了 kimi。
说法是一样的,那就可能是我的测试用例有问题?
请各位朋友多指教。
转载自:https://juejin.cn/post/7347943210952998922