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

时间:2012-05-11 00:36:15

标签: scala scala-collections

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

稍后编辑:我发现可能使用集合时可能存在很多情况。在可能的情况下使用Sets或仅在真正需要设置功能时使用它是否合适?

2 个答案:

答案 0 :(得分:9)

是的,在所有集合数据结构中,数组在您事先知道其大小时,其开销的开销最小。

如果您不提前知道尺寸,我仍会选择 ArrayBuffer * 。用于在空间不足时扩展底层数组的算法就像它获得的效率一样高效。

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

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

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

另外,要特别注意可变数据结构的视图。视图不捕获底层数据结构的状态。当它改变时,视图也会改变。但是,不可变数据结构的视图表现得非常好。最后,视图显然包含对底层数据结构的引用,这意味着当程序保留在视图上时,它不会被垃圾收集。

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

答案 1 :(得分:3)

需要来存储元素吗?你不能按需计算它们吗?如果您可以按需计算值而不是存储它们,您可以创建一个TraversableIterable来完成工作,几乎不花费任何内存(Traversable没有花费内存,除了班级本身)。