scala HashSet [String] .contains大大降低了app的速度

时间:2015-02-26 14:26:19

标签: performance scala hashmap contains

我有一个小型ETL-Like应用程序,它从多个来源获取一些数据,通过一些API规则将它们组合起来,最后将它们吐出到目标文件中。

这些项目具有计算出的唯一ID-String,并且由于多个源和API规则的混合,可能会发生两次或更多次生成相同目标对象的情况。听起来很奇怪,但细节很有道理。不幸的是,我在导出之前无法检测到它。

要让每个唯一ID对象只导出一次,我认为我可以存储它们的ID并通过以下方式进行比较:

private val Ids = new mutable.HashSet[String]
def write(entity:Entity) {
  val eID = entity.id.intern
  Ids.synchronized { // i somethimes use .par.map and call write()
    if(Ids.contains(eID)) {
      return
    }

    Ids += eID
  }
  .. process

现在可以正常工作一段时间,但在该hashset中有~50.000.000个元素,它会大大减慢整个过程。

我使用32Gig的字符串重复数据删除xmx / xms启动应用程序。它只使用大约9 Gig最大值,因此不知道是什么导致减速..我将StringTableSize设置为天文尺寸以及有意义的高尺寸,没有明显的变化。

我的想法是比较生殖器中的坏蛋吗?还是hashset的选择?有什么建议可以调试吗?香蕉?

如果我注释掉Ids.contains和+ =行,我的应用大约需要17分钟。 id comparsion启用了几个小时。

任何想法/线索/建议?

我的想法一般比较坏吗? 还是hashset的选择? 任何建议什么/如何调试?使用VisualVM,我只花了大约60%的时间花在contains-method上。

可能它只是好吗需要这么长时间,因为对于每个第n个元素,我有n-1个比较..?

提前致谢。

Scala 2.11.5

1 个答案:

答案 0 :(得分:0)

我不确定这是否与scala HashSet有关。罪魁祸首是String #intern方法,它有一些严重的性能问题。见Performance penalty of String.intern()

如果您希望实习以确保您可以在工作集中进行计算,则必须编写自己的实习生表。编写一个好的高性能实习表可能非常棘手。因此,如果您能够负担对番石榴的依赖,请使用Guava Cache。

您是否尝试完全放弃实习?

相关问题