When profiling my application, I can see boxing of Double values done in the Array[Double] constructor, like this (copied from JMC / JFR):
Double Double.valueOf(double) 1472
Double BoxesRunTime.boxToDouble(double) 1472
Object WrappedArray$ofDouble.apply(int) 1468
Object IndexedSeqLike$Elements.next() 1365
void Iterator.foreach(Function1) 1365
void Iterator.foreach$(Iterator, Function1) 1365
void AbstractIterator.foreach(Function1) 1365
Object Array$.apply(Seq, ClassTag) 1365
When I check the Array constructor code, there is the following comment (see Array.scala#L182-L192):
// Subject to a compiler optimization in Cleanup.
// Array(e0, ..., en) is translated to { val a = new Array(3); a(i) = ei; a }
Such translation sounds like a reasonable thing to do. Why am I still seeing the Iterator / boxToDouble in my callstacks? Is the comment somehow obsolete, or do I need some specific compiler settings for this optimization to be applied?
The code calling the array constructor is a class member initialization:
var elements = Array[Double](
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
)
I have tested this with Scala 2.12.12 and 2.13.3
The comment was added in a commit Optimize primitive Array(e1, ..., en) (in Scala 2.11.0-M1).