Scala Seq vs List性能

时间:2017-03-21 22:11:09

标签: scala jvm scala-collections

所以我有点困惑。我在Scala中有一段代码(确切的代码并不是那么重要)。我把所有的方法写成了Seq [T]。这些方法主要是尾递归,并使用Seq [T]作为累加器,它最初像Seq()一样被馈送。有趣的是,当我将所有签名与具体的List()实现交换时,我观察到性能提高了三倍。

是不是Seq的默认实现实际上是一个不可变的List?那么如果是这样的话,究竟发生了什么?

1 个答案:

答案 0 :(得分:1)

致电Seq(1,2,3)并致电List(1,2,3)都会产生1 :: 2 :: 3 :: NilSeq.apply方法只是一个非常通用的方法,如下所示:

def apply[A](elems: A*): CC[A] = {
  if (elems.isEmpty) empty[A]
  else {
    val b = newBuilder[A]
    b ++= elems
    b.result()
  }
}

newBuilder在这里很重要。 That method代表scala.collection.immutable.Seq.newBuilder

def newBuilder[A]: Builder[A, Seq[A]] = new mutable.ListBuffer

因此Builder的{​​{1}}是Seq。通过将元素附加到空mutable.ListBuffer然后在其上调用result来构建Seq,其实现如下:

ListBuffer

def result: List[A] = toList /** Converts this buffer to a list. Takes constant time. The buffer is * copied lazily, the first time it is mutated. */ override def toList: List[A] = { exported = !isEmpty start } 也有List ListBuffer。它经历了一个略有不同但相似的建筑过程。无论如何,这并不会产生很大的不同,因为我认为你的大多数算法都会在Builder之前添加内容,而不是一直调用Seq。即使你这样做也不应该有太大的不同。

在没有看到具有该行为的代码的情况下,真的无法说出导致您所看到的行为的原因。