summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-11-29 17:33:03 +0100
committerPaul Phillips <paulp@improving.org>2012-12-27 15:47:19 -0800
commit3f9943be7ad9de6a3443befaec1613682dbd0129 (patch)
tree20509777341024fbd22d7802fdaac2e42b80c209
parent5b5635ee9d227ff61834f5a538d0f8082192f9b6 (diff)
downloadscala-3f9943be7ad9de6a3443befaec1613682dbd0129.tar.gz
scala-3f9943be7ad9de6a3443befaec1613682dbd0129.tar.bz2
scala-3f9943be7ad9de6a3443befaec1613682dbd0129.zip
Eliminate allocations in ListBuffer.
++= on a linear sequence can be accomplished without closure allocation.
-rw-r--r--src/library/scala/collection/mutable/ListBuffer.scala20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala
index b7b487964c..e059f31929 100644
--- a/src/library/scala/collection/mutable/ListBuffer.scala
+++ b/src/library/scala/collection/mutable/ListBuffer.scala
@@ -11,6 +11,7 @@
package scala.collection
package mutable
+import scala.annotation.tailrec
import generic._
import immutable.{List, Nil, ::}
import java.io._
@@ -178,8 +179,23 @@ final class ListBuffer[A]
this
}
- override def ++=(xs: TraversableOnce[A]): this.type =
- if (xs.asInstanceOf[AnyRef] eq this) ++= (this take size) else super.++=(xs)
+ private def ++=(elems: collection.LinearSeq[A]): this.type = {
+ @tailrec def loop(xs: collection.LinearSeq[A]) {
+ if (xs.nonEmpty) {
+ this += xs.head
+ loop(xs.tail)
+ }
+ }
+ loop(elems)
+ this
+ }
+
+ override def ++=(xs: TraversableOnce[A]): this.type = xs match {
+ case x: AnyRef if x eq this => this ++= (this take size)
+ case xs: collection.LinearSeq[_] => this ++= xs
+ case _ => super.++=(xs)
+
+ }
override def ++=:(xs: TraversableOnce[A]): this.type =
if (xs.asInstanceOf[AnyRef] eq this) ++=: (this take size) else super.++=:(xs)