Skip to content

Commit f309513

Browse files
committed
A conceivably pretty bad performance bug in bui...
A conceivably pretty bad performance bug in builders. SI-4821 pointed out that ArrayBuffer's ++ checks for a cheap size method by matching on IndexedSeq, but mutable.IndexedSeq, so all immutable collections are thrown in the same group as linear seqs. I went looking for other examples of this and found them, in key classes like Builder. The "type shadowing trap" is a serious issue in the collections. Closes SI-4821, no review.
1 parent abc851a commit f309513

File tree

3 files changed

+4
-4
lines changed

3 files changed

+4
-4
lines changed

src/library/scala/collection/mutable/ArrayBuffer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class ArrayBuffer[A](override protected val initialSize: Int)
8989
* @return the updated buffer.
9090
*/
9191
override def ++=(xs: TraversableOnce[A]): this.type = xs match {
92-
case v: IndexedSeq[_] =>
92+
case v: collection.IndexedSeqLike[_, _] =>
9393
val n = v.length
9494
ensureSize(size0 + n)
9595
v.copyToArray(array.asInstanceOf[scala.Array[Any]], size0, n)

src/library/scala/collection/mutable/ArrayOps.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza
6565
*/
6666
def flatten[U, To](implicit asTrav: T => collection.Traversable[U], m: ClassManifest[U]): Array[U] = {
6767
val b = Array.newBuilder[U]
68-
b.sizeHint(map{case is: IndexedSeq[_] => is.size case _ => 0} sum)
68+
b.sizeHint(map{case is: collection.IndexedSeq[_] => is.size case _ => 0} sum)
6969
for (xs <- this)
7070
b ++= asTrav(xs)
7171
b.result

src/library/scala/collection/mutable/Builder.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ trait Builder[-Elem, +To] extends Growable[Elem] {
6565
* @param delta a correction to add to the `coll.size` to produce the size hint.
6666
*/
6767
def sizeHint(coll: TraversableLike[_, _], delta: Int = 0) {
68-
if (coll.isInstanceOf[IndexedSeqLike[_,_]]) {
68+
if (coll.isInstanceOf[collection.IndexedSeqLike[_,_]]) {
6969
sizeHint(coll.size + delta)
7070
}
7171
}
@@ -83,7 +83,7 @@ trait Builder[-Elem, +To] extends Growable[Elem] {
8383
* than collection's size are reduced.
8484
*/
8585
def sizeHintBounded(size: Int, boundingColl: TraversableLike[_, _]) {
86-
if (boundingColl.isInstanceOf[IndexedSeqLike[_,_]])
86+
if (boundingColl.isInstanceOf[collection.IndexedSeqLike[_,_]])
8787
sizeHint(size min boundingColl.size)
8888
}
8989

0 commit comments

Comments
 (0)