在JavaScript中,Set和Map的性能有什么区别?

简介: 在JavaScript中,Set和Map的性能有什么区别?

在 JavaScript 中,SetMap 的底层实现均基于哈希表(Hash Table),因此在大多数操作上性能表现相近,但由于设计目的不同,仍存在细微差异。以下是两者性能的详细对比及适用场景分析:

一、核心操作的时间复杂度

操作 Set Map 说明
添加元素 add(value) set(key, value) 均为 O(1) 平均时间复杂度
删除元素 delete(value) delete(key) 均为 O(1) 平均时间复杂度
检查存在性 has(value) has(key) 均为 O(1) 平均时间复杂度
获取元素数量 size size 均为 O(1) 直接返回属性值
遍历所有元素 values() entries() 均为 O(n) 需遍历所有元素
清空集合 clear() clear() 均为 O(1) 重置内部状态

二、性能差异的具体场景

1. 添加与查找操作

  • Set:适用于存储单一值的集合,添加和查找时无需处理键值对映射,略快于 Map。

    const set = new Set();
    set.add(1); // 直接存储值,无需键
    console.log(set.has(1)); // O(1),查找速度快
    
  • Map:需维护键值对映射,操作略复杂,但仍保持 O(1) 时间复杂度。

    const map = new Map();
    map.set("key", 1); // 需处理键值对
    console.log(map.get("key")); // O(1),但多一步键的哈希计算
    

2. 键的类型对性能的影响

  • Set:仅存储值,无需计算键的哈希值,性能稍优。
  • Map:键可以是任意类型(包括对象),需为每个键计算哈希值,开销略高。
    const objKey = {
         };
    map.set(objKey, "value"); // 对象键需额外计算哈希值
    

3. 大数据量下的内存占用

  • Set:仅存储值,内存占用相对较小。
  • Map:需存储键值对,内存占用约为 Set 的两倍(相同数量的元素)。

三、性能测试示例

以下代码对比了 Set 和 Map 在大数据量下的插入和查找性能:

// 测试环境:Chrome 浏览器,100万条数据
const size = 1000000;

// 测试 Set
const set = new Set();
console.time("Set add");
for (let i = 0; i < size; i++) {
   
  set.add(i);
}
console.timeEnd("Set add"); // 约 20-30ms

console.time("Set has");
for (let i = 0; i < size; i++) {
   
  set.has(i);
}
console.timeEnd("Set has"); // 约 15-25ms

// 测试 Map
const map = new Map();
console.time("Map set");
for (let i = 0; i < size; i++) {
   
  map.set(i, i);
}
console.timeEnd("Map set"); // 约 30-40ms

console.time("Map get");
for (let i = 0; i < size; i++) {
   
  map.get(i);
}
console.timeEnd("Map get"); // 约 25-35ms

结果说明

  • 插入操作:Map 比 Set 慢约 30%,因需处理键值对。
  • 查找操作:Map 比 Set 慢约 20%,因需额外处理键的哈希值。

四、性能优化建议

  1. 优先使用 Set 存储单一值集合
    若只需存储唯一值且无需键值映射,Set 的性能和内存效率均优于 Map。

  2. 仅在需要键值映射时使用 Map
    Map 的优势在于支持任意类型的键,且遍历时保持插入顺序,适合缓存、映射关系等场景。

  3. 避免频繁删除和重新添加元素
    哈希表在删除元素后可能不会立即释放内存,频繁删除添加可能导致内存碎片。

  4. 大数据量下的遍历优化
    若需频繁遍历集合,Set 和 Map 的性能相近,但需注意 Map 返回的是键值对,处理开销略高。

五、总结:如何根据性能选择?

场景 推荐使用 Set 推荐使用 Map
存储唯一值集合 ✅ 性能和内存效率更高 ❌ 内存占用多,操作略慢
快速检查元素存在性 ✅ 略快于 Map ❌ 键值对处理开销略高
需要键值映射关系 ❌ 不支持键值对 ✅ 设计初衷即为此场景
键的类型为对象或函数 ❌ 无法通过对象查找 ✅ 支持任意类型的键
大数据量下的频繁插入/删除 ✅ 略优 ❌ 略慢(但仍为 O(1))

理解两者性能差异后,可根据具体业务需求选择合适的数据结构,在保证功能正确性的同时优化性能。

目录
相关文章
|
5月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
346 1
|
8月前
|
存储 缓存 JavaScript
Set和Map有什么区别?
Set和Map有什么区别?
570 1
|
9月前
|
存储 JavaScript 前端开发
Set中的add()方法和数组的push()方法有什么区别?
Set中的add()方法和数组的push()方法有什么区别?
480 122
|
9月前
|
存储 JavaScript 前端开发
for...of循环在遍历Set和Map时的注意事项有哪些?
for...of循环在遍历Set和Map时的注意事项有哪些?
417 121
|
9月前
|
存储 编译器 容器
set、map、multiset、multimap的介绍及使用以及区别,注意事项
set是按照一定次序存储元素的容器,使用set的迭代器遍历set中的元素,可以得到有序序列。set当中存储元素的value都是唯一的,不可以重复,因此可以使用set进行去重。set默认是升序的,但是其内部默认不是按照大于比较,而是按照小于比较。set中的元素不能被修改,因为set在底层是用二叉搜索树来实现的,若是对二叉搜索树当中某个结点的值进行了修改,那么这棵树将不再是二叉搜索树。
317 0
|
9月前
|
安全 Java 数据库连接
让我们讲解一下 Map 集合遍历的方式
我是小假 期待与你的下一次相遇 ~
329 43
|
12月前
使用 entrySet 遍历 Map 类集合 KV
使用 entrySet 遍历 Map 类集合 KV
|
存储 前端开发 API
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
该文章详细介绍了ES6中Set和Map数据结构的特性和使用方法,并探讨了它们在前端开发中的具体应用,包括如何利用这些数据结构来解决常见的编程问题。
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
|
存储 安全 Java
java集合框架复习----(4)Map、List、set
这篇文章是Java集合框架的复习总结,重点介绍了Map集合的特点和HashMap的使用,以及Collections工具类的使用示例,同时回顾了List、Set和Map集合的概念和特点,以及Collection工具类的作用。
java集合框架复习----(4)Map、List、set
|
Go 定位技术 索引
Go 语言Map(集合) | 19
Go 语言Map(集合) | 19