Scala:最有效的简单迭代集合

标签 scala scala-collections

我经常按需生成集合以节省实例数据大小。在收集垃圾之前,消费者可能只迭代一次收集。消费者不关心集合的顺序,不需要对它进行排序,当然不需要改变它,或者它的任何元素。 Scala 中最有效的类型安全集合是什么? - 数组?

后来的编辑:我想到可能有很多情况我可以使用 Sets。在可能的情况下使用 Set 还是只在真正需要 set 功能时才使用它们好?

最佳答案

是的,在所有集合数据结构中, 数组 的开销最少 当您提前知道它们的大小时

如果您事先不知道大小,我仍然会选择 ArrayBuffer* 。用于在空间不足时扩展底层数组的算法尽可能有效。

不要* 使用(链接的) 列表 因为这些类涉及每个元素的一个堆分配。现代 JVM 垃圾收集器很好,但它们不是免费工作的。

*:但请参阅 @user unknown 对该问题的评论以获取指向某些微基准的链接。当前的 ArrayBuffer 实现可能不是最理想的。

另请查看 .view 。通常您不需要实际存储中间结果。相反,您可以使用 .map.filter 和其他方法来构建集合的“描述”。操作(映射、过滤器等)只会在您迭代集合时执行,通常在 O(1) 空间中。缺点是,每次查询这些 View 时都会重新计算它们。 (尽管使用简单的过滤器和庞大的底层集合可能仍然更有效)

此外,对可变数据结构的 View 要格外小心。 View 不捕获底层数据结构的状态。当它改变时, View 也会改变。然而,关于不可变数据结构的 View 表现得非常好。最后, View 显然包含对底层数据结构的引用,这意味着当您的程序保留 View 时它不会被垃圾收集。

(更新)
向量 似乎在存储效率与灵活性之间取得了很好的平衡,尤其是对于大序列。

关于Scala:最有效的简单迭代集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10543938/

相关文章:

arrays - 直观地解释为什么 `List` 是协变的,而 `Array` 是不变的?

用于分组的 Scala 集合,同时保持顺序

scala - SBT Scala 跨版本,具有聚合和依赖关系

scala - 在 spark 中设置 textinputformat.record.delimiter

scala - 值 unsafePerformSync 不是 scalaz.concurrent.Task[String] 的成员

scala - 声明和初始化实例/类变量的首选方式

scala - 在 Scala 中编写带有偏移量的通用 takeWhile

scala - 如何展平析取类型

scala - 组合任意长度的多个列表

scala - 如何检查scala中的返回值类型