通常我会按需生成一个集合以节省实例数据的大小。消费者在收集垃圾之前可能只迭代一次集合。消费者不关心集合的顺序,不需要对其进行排序,当然也不需要改变它,或者它的任何元素。Scala 中最有效的类型安全集合是什么?- 数组?
后期编辑:我突然想到,在很多情况下我可以使用 Sets。尽可能使用 Sets 好还是只在真正需要 set 功能时使用它们?
通常我会按需生成一个集合以节省实例数据的大小。消费者在收集垃圾之前可能只迭代一次集合。消费者不关心集合的顺序,不需要对其进行排序,当然也不需要改变它,或者它的任何元素。Scala 中最有效的类型安全集合是什么?- 数组?
后期编辑:我突然想到,在很多情况下我可以使用 Sets。尽可能使用 Sets 好还是只在真正需要 set 功能时使用它们?
是的,在所有集合数据结构中,如果事先知道数组的大小,数组的开销最少。
如果您不提前知道大小,我仍然会选择ArrayBuffer*。用于在空间不足时扩展底层数组的算法尽可能高效。
不要*使用(链接的)列表或流,因为这些类涉及每个元素一个堆分配。现代 JVM 垃圾收集器很好,但它们不是免费工作的。
*:但请参阅@user unknown对问题的评论以获取一些微基准的链接。当前的ArrayBuffer
实现可能不是最理想的。
也看看.view
。通常您不需要实际存储中间结果。相反,您可以使用.map
,.filter
和其他人来构建集合的“描述”。操作(映射、过滤器等)只会在您迭代集合时执行,通常是在O(1)
空间中。不利的一面是,每次查询这些视图时都会重新计算它们。(尽管使用简单的过滤器和庞大的底层集合可能仍然更有效)
另外,对可变数据结构的视图要格外小心。视图不捕获底层数据结构的状态。当它改变时,视图也会改变。然而,关于不可变数据结构的视图表现得非常好。最后,视图显然包含对底层数据结构的引用,这意味着当您的程序保留视图时,它不会被垃圾收集。
(更新) 向量似乎在存储效率和灵活性之间取得了很好的平衡,特别是对于大序列。
你需要存储元素吗?你不能按需计算它们吗?如果您可以按需计算值而不是存储它们,您可以创建一个Traversable
或 anIterable
来完成这项工作,几乎不需要任何内存(Traversable
除了类本身之外,没有任何内存)。