我正在与一位同事进行一些测试,我们正在从数据库中提取数据(大约350,000条记录),将每条记录转换为一个对象和一个关键对象,然后将它们填充到ImmutableMap.Builder中。

当我们调用build()方法时,它花了很长时间,这可能是由于ImmutableMap附带了所有数据完整性检查(重复键,空值等)。公平地说,我们也尝试使用哈希图,这花了一段时间,但时间不长于ImmutableMap。我们最终只使用了ConcurrentHashMap,在迭代记录时我们填充了9个线程,并将其包装在不可修改的映射中。表现不错。

我在阅读的文档中注意到ImutableMap并未针对“equals()”操作进行优化。作为顽固的不可变主义者,我希望ImmutableMap可用于大数据量,但我感觉这并不意味着要这样做。这个假设正确吗?是否仅针对中小型数据集进行了优化?我是否需要通过“copyOf()”或其他方法调用隐藏的实现?

最佳答案

我的经验是,Java内置的Collection类中没有一个真正针对大量性能进行过优化。例如,一旦hashCode用作数组中的索引,HashMap就使用简单的迭代,并通过equals将键与具有相同哈希值的每个项目进行比较。如果要在 map 上存储几百万个项目,则需要设计良好的哈希和大容量。这些类被设计为尽可能通用和安全。

因此,如果您希望坚持使用标准Java HashMap,可以尝试进行性能优化:

  • 确保您的哈希函数提供的分布尽可能接近均匀分布。许多域的值均存在偏差,因此您的哈希值必须考虑到这一点。
  • 当您有大量数据时,HashMap将被扩展很多倍。理想情况下,将初始容量设置为尽可能接近最终值。
  • 确保您的equals实现尽可能高效。

  • 如果您知道(例如) key 是整数,则可以应用大量的性能优化,例如,在应用哈希之后使用某种形式的btree并使用==而不是equals

    因此,简单的答案是,我相信您将需要编写自己的集合来获得所需的性能,或者使用可用的更优化的实现之一。

    关于java - ImmutableMap是大量键/对象/的次佳选择吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28268682/

    10-09 00:08