Skip to content

Commit 96782f6

Browse files
committed
Faster Array[T](t) for @specialialized T.
Avoid boxing the elements in favour of bulk clone of the varargs array into the result array, when the runtime type of the class-tag-generated result array is the same as the varargs array.
1 parent cc02de6 commit 96782f6

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

library/src/scala/Array.scala

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
package scala
1414

1515
import scala.collection.generic._
16-
import scala.collection.{ mutable, immutable }
17-
import mutable.{ ArrayBuilder, ArraySeq }
18-
import scala.reflect.ClassTag
19-
import scala.runtime.ScalaRunTime.{ array_apply, array_update }
16+
import scala.collection.{immutable, mutable}
17+
import mutable.{ArrayBuilder, ArraySeq}
18+
import scala.reflect.{ClassTag, classTag}
19+
import scala.runtime.ScalaRunTime
20+
import scala.runtime.ScalaRunTime.{array_apply, array_update}
2021

2122
/** Contains a fallback builder for arrays when the element type
2223
* does not have a class tag. In that case a generic array is built.
@@ -194,10 +195,20 @@ object Array extends FallbackArrayBuilding {
194195
// Subject to a compiler optimization in Cleanup.
195196
// Array(e0, ..., en) is translated to { val a = new Array(3); a(i) = ei; a }
196197
def apply[T: ClassTag](xs: T*): Array[T] = {
197-
val array = new Array[T](xs.length)
198-
var i = 0
199-
for (x <- xs.iterator) { array(i) = x; i += 1 }
200-
array
198+
val len = xs.length
199+
xs match {
200+
case wa: mutable.WrappedArray[_] if wa.elemTag == classTag[T] =>
201+
// We get here in test/files/run/sd760a.scala, `Array[T](t)` for
202+
// a specialized type parameter `T`. While we still pay for two
203+
// copies of the array it is better than before when we also boxed
204+
// each element when populating the result.
205+
ScalaRunTime.array_clone(wa.array).asInstanceOf[Array[T]]
206+
case _ =>
207+
val array = new Array[T](len)
208+
var i = 0
209+
for (x <- xs.iterator) { array(i) = x; i += 1 }
210+
array
211+
}
201212
}
202213

203214
/** Creates an array of `Boolean` objects */

0 commit comments

Comments
 (0)