【问题标题】:Merging huge sets (HashSet) in Scala在 Scala 中合并大集合 (HashSet)
【发布时间】:2011-08-03 11:17:42
【问题描述】:

我有两个巨大的(如数百万个条目)集合(HashSet),它们之间有一些(

目前,我正在将一组中的所有项目添加到另一组中:

setOne ++= setTwo

这需要几分钟才能完成(在多次尝试调整成员的 hashCode() 之后)。

任何想法如何加快速度?

【问题讨论】:

  • 这些是可变集合,对吧?
  • 合并后的集合怎么办?有哪些操作,有多少? (我想你可以采取一种懒惰的方法,如果你会用它做少量的事情,那么根本不用费心合并这些集合 - 只需根据需要对一个或两个集合进行操作)
  • 你知道性能是否受内存堆大小的影响吗?有时,当 JVM 用完堆时,性能会下降,因为垃圾收集器会花费所有时间来回收内存。
  • @huynhjl 你的观点是有效的。我最初确实遇到了严重的退化,但通过将享元应用于集合成员来修复它。
  • @Paul:在这种特殊情况下,我只是将集合保存到一个文本文件中,这样就可以了。然而,这个问题的重点是真正找到改进大集合合并的方法......

标签: scala collections scala-collections


【解决方案1】:

在 Scala 2.9.0+ 中使用 Parallel Collections API 可以获得更好的性能:

setOne.par ++ setTwo

(setOne.par /: setTwo)(_ + _)

【讨论】:

    【解决方案2】:

    您可能想尝试一些事情:

    • 使用sizeHint 方法将您的集合保持在预期大小。
    • 调用useSizeMap(true) 以获得更好的哈希表调整大小。

    在我看来,后一个选项可以提供更好的结果,尽管两者都在此处显示了测试的改进。

    【讨论】:

    • 这通常很有用。不幸的是,我正在进行蛮力搜索,不知道各个集合的大小是多少;至少在我计算出来之前不会……
    • @Alexandros 您可以随时在每个集合上调用size 并估计合并的大小。或者使用useSizeMap,它不需要你告诉它任何事情。
    【解决方案3】:

    你能告诉我更多关于集合内的数据吗?我问的原因是,对于这种事情,你通常想要一些专业的东西。以下是一些可以做的事情:

    • 如果数据已(或可以)排序,您可以遍历指针进行合并,类似于使用合并排序所做的操作。此操作非常容易并行化,因为您可以对一个数据集进行分区,然后使用二分搜索对第二个数据集进行分区以找到正确的边界。
    • 如果数据在某个数字范围内,您可以改用位集,只要遇到该数字就设置位。
    • 如果其中一个数据集小于另一个,您可以将其放入一个哈希集中并快速循环另一个数据集,检查是否包含。

    我使用第一种策略在大约一秒钟内从大约 40k 个较小的集合中创建了一个包含大约 800 万个整数的巨大集合(在强大的硬件上,在 Scala 中)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 2012-10-03
      • 1970-01-01
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多