我和一位同事一起做了一些测试,我们从数据库中提取数据(大约 350,000 条记录),将每条记录转换为一个对象和一个关键对象,然后将它们填充到一个 ImmutableMap.Builder 中。
当我们调用 build() 方法时,它花了很长时间,可能是由于 ImmutableMap 附带的所有数据完整性检查(重复键、空值等)。公平地说,我们也尝试使用 HashMap ,这花了一些时间,但没有 ImmutableMap 长。我们最终决定只使用 ConcurrentHashMap,我们在迭代记录时填充了 9 个线程,并将其包装在一个不可修改的映射中。表现很好。
我在其阅读的文档中注意到 ImutableMap 并未针对“equals()”操作进行优化。作为一个顽固的不可变主义者,我希望 ImmutableMap 能够处理大量数据,但我觉得它并不适用于此。这个假设对吗?它是否仅针对小型/中型数据集进行了优化?是否有我需要通过“copyOf()”或其他方式调用的隐藏实现?
最佳答案
我猜你的 key.equals()
是一个耗时的方法。
key.equals()
将在 ImmutableMap.build()
中被调用更多次 比 HashMap.put()
(在一个循环中)。 key.hashCode()
同时被调用,HashMap.put()
和 ImmutableMap.build()
。因此,如果 key.equals()
耗时较长,则整个持续时间可能会相差很多。
key.equals()
在 HashMap.put()
期间被调用了几次(好的散列算法会导致一些冲突)。
而在 ImmutableMap.build()
的情况下,key.equals()
将在 checkNoConflictInBucket()
时被调用多次。 key.equals()
的复杂度为 O(n)。
一旦构建了 map ,两种类型的 map 在访问时应该不会有太大差异,因为它们都是基于哈希的。
样本:
有 10000 个随机字符串作为键。 HashMap.put()
调用
String.equals()
2 次,而 ImmutableMap.build()
调用 3000 次。
关于java - ImmutableMap 是大量键/对象/的次优选择吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28268682/