两个List构造在编译/内存占用方面是否相同?
val list1 = x1 :: x2 :: x3 :: Nil
val list2 = List(x1, x2, x3)
我认为list1
代价更高,因为每个h :: t
创建一个List,然后将每个新元素连接起来(产生一个新列表)直到最终列表。虽然list2
一次创建了一个列表。
答案 0 :(得分:7)
我认为,第一个更有效:它实际上从右到左,并且将元素添加到列表实际上非常便宜,就像创建案例类的新实例一样便宜:{{1} }
另一种方式实际上是一个varargs调用,因此,它首先创建一个新数组,并将所有变量放在那里,然后将其包装到def ::(x: T) = new scala.collection.immutable.::(x, this)
中,然后执行Seq
,最后进行通过类似(但更多参与/昂贵)的方式将Seq.toList
的元素逐个添加到新列表中。
所以,第一种方式更有效,但我怀疑差异实际上是可以在任何类型的代码中检测到,您可以手动输入。
答案 1 :(得分:0)
使用List构造函数,每行编写一个list元素时将避免错误。例如,对于缺点,可能会编写以下错误:
val list =
x1 ::
x2 ::
x3
x4 ::
Nil
它可以编译为list == List(x1, x2, x3)
,而不是所需的List(x1, x2, x3, x4)
,但是绝对不是假定的。
与List构造函数比较:
val list = List(
x1,
x2,
x3,
x4
)
如果您忘记在某些行的末尾使用逗号,则会发生编译错误。
在性能方面,第一种方法效率更高(请查看@dima的答案),但是您几乎永远看不到这一点。