安EnumMap
使用映射的所有键都来自同一 enum
的限制来获得性能优势:
Enum maps are represented internally as arrays. This representation is extremely compact and efficient.
在这种情况下,键和值存储在单独的数组中,并且值按序号排序。迭代是通过内部 EnumMapIterator
类完成的。
由各种 Map.of
创建的不可变映射方法使用映射不会在结构上发生变化的限制来获得性能优势。如果映射的大小不是 0 或 1,则它使用 MapN 内部类,该内部类也将其条目存储在数组中。在这种情况下,该值存储在其键之后的 1 个索引处。迭代是通过内部 MapNIterator
完成的。
对于大小为 2 或更大的 enum
键的不可变映射,它满足上述两个要求,哪个映射性能更好? (标准可以是 containsKey
、containsValue
、get
的空间效率、时间效率以及 entrySet
的迭代效率, keySet
和 value
。)
最佳答案
which map gives better space efficiency, and time efficiency for its operations and iteration:
containsKey
,containsValue
,get
,entrySet
,keySet
andvalues
?
你提出了 1 + 6(或 2 * 6,取决于如何理解)的问题,这有点太多了。如果你想要一个明确的答案,你必须专注于一件事并分析它(除非你发现一个非常有趣的问题,否则没有人会为你做这件事)。
<小时/>EnumMap
的空间效率必须更高。无需存储键,因为可以使用共享枚举数组。不需要a holes-containing hash lookup array .
可能会有异常(exception),例如基于巨大枚举的小 map 。
<小时/>最重要的操作是get
。使用EnumMap
,it involves no lookup ,只是一个trivial class comparison和数组访问。对于 Map.of(...)
,有一个 loop ,对于枚举,通常在第一次迭代后终止,因为 Enum.hashCode
为 IMHO stupid ,但通常分布良好。
由于 containsKey
基于相同的查找,所以很清楚。
我怀疑,我曾经使用过 containsValue
,但它并没有做任何比线性搜索更智能的事情。由于存在漏洞(需要简单的空测试,但会导致分支错误预测),我预计 EnumMap 会取得微小的胜利。
剩下的三个操作不值得查找,因为它们返回一个不包含数据的集合,只是指向 map ,即恒定时间操作。例如,map.keySet().contains(x)
只是委托(delegate)给 map.containsKey()
。
迭代的效率会是一个更有趣的问题,但你没有问。
关于java - Map.of 与 EnumMap 用于具有枚举键的不可变映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52281364/