为什么 EnumSet 或 EnumMap 可能比它们的散列对应物性能更高?

2022-09-04 19:57:34

以下是来自EnumMap的Java文档的实现说明部分:

实现说明:所有基本操作都以恒定时间执行。它们可能(尽管不能保证)比HashMap的对应物更快。

我在java文档中也看到了类似的行。我想知道为什么它更有可能并且会比他们的散列对应物更快?EnumSetEnumSetsEnumMaps


答案 1

EnumSet由位数组支持。由于您可以放入的不同项目的数量是事先知道的,因此我们可以为每个枚举值保留一位。您可以想象对 或 进行类似的优化,但对于(2^32 位需要 0.5 GiB 内存)或一般情况下,这是不可行的。EnumSetSet<Byte>Set<Short>Set<Integer>

因此,基本操作如或ar常量时间(就像),但它们只需要检查或设置一个位。无计算。这就是为什么更快。还有更复杂的操作,如联合或使用位操作技术轻松实现。existsaddHashSethashCode()EnumSet

在 OpenJDK 中,有两种实现:能够处理多达 64 值的枚举和更大的枚举(使用 long[])。但这只是一个实现细节。EnumSetRegularEnumSetJumboEnumSet

EnumMap基于类似的原理工作,但它用于存储值,而键(索引)是从 隐式推断出来的。Object[]Enum.ordinal()


答案 2

EnumSet在内部使用数组[]和自然顺序,并产生后果:

  • 快速:get/set 由常数时间 O(1) 调用,不用于查找正确的桶hashCode()
  • 内存效率:数组的大小由枚举大小预定义,不是动态的

EnumMap使用 Enum 作为基于相同主体的键,因为在不可能发生哈希代码冲突的情况下EnumSet