【发布时间】:2015-02-26 14:26:18
【问题描述】:
我有一个类似 ETL 的小型应用程序,它从多个来源获取一些数据,通过一些 API 规则将它们组合起来,最后将它们吐出到目标文件中。
这些项目具有计算出的唯一 ID 字符串,并且由于多个源和 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
现在这在一段时间内可以正常工作,但在该哈希集中有大约 50.000.000 个元素,它会大大减慢整个过程。
我以 32Gig 的字符串重复数据删除、xmx/xms 启动应用程序。它只使用大约 9 Gig max,所以不知道是什么导致了速度变慢。我将 StringTableSize 设置为天文尺寸以及高大的尺寸,没有明显的变化。
我的想法是在一般情况下比较坏吗?还是哈希集的选择?有什么建议可以调试吗?香蕉?
如果我注释掉 Ids.contains 和 += 行,我的应用程序大约需要 17 分钟。使用 id 比较启用了几个小时。
有什么想法/线索/建议吗?
我的总体比较不好的想法吗? 还是哈希集的选择? 有什么建议/如何调试?使用 VisualVM,我只花费了大约 60% 的时间在包含方法上。
可能可以花这么长时间,因为对于每个第 n 个元素,我有 n-1 个比较..?
提前致谢。
Scala 2.11.5
【问题讨论】:
标签: performance scala hashmap contains