abstract class AbsArray[T] { def apply(idx: Int): T def update(idx: Int, elem: T): Unit def length: Int def applyByte(idx: Int): Byte = apply(idx).asInstanceOf[Byte] def updateByte(idx: Int, elem: Byte) = update(idx, elem.asInstanceOf[T]) def applyChar(idx: Int): Char = apply(idx).asInstanceOf[Char] def updateChar(idx: Int, elem: Char) = update(idx, elem.asInstanceOf[T]) def applyShort(idx: Int): Short = apply(idx).asInstanceOf[Short] def updateShort(idx: Int, elem: Short) = update(idx, elem.asInstanceOf[T]) def applyInt(idx: Int): Int = apply(idx).asInstanceOf[Int] def updateInt(idx: Int, elem: Int) = update(idx, elem.asInstanceOf[T]) def applyLong(idx: Int): Long = apply(idx).asInstanceOf[Long] def updateLong(idx: Int, elem: Long) = update(idx, elem.asInstanceOf[T]) def applyFloat(idx: Int): Float = apply(idx).asInstanceOf[Float] def updateFloat(idx: Int, elem: Float) = update(idx, elem.asInstanceOf[T]) def applyDouble(idx: Int): Double = apply(idx).asInstanceOf[Double] def updateDouble(idx: Int, elem: Double) = update(idx, elem.asInstanceOf[T]) def applyBoolean(idx: Int): Boolean = apply(idx).asInstanceOf[Boolean] def updateBoolean(idx: Int, elem: Boolean) = update(idx, elem.asInstanceOf[T]) def applyObject(idx: Int): Object = apply(idx).asInstanceOf[Object] def updateObject(idx: Int, elem: Object) = update(idx, elem.asInstanceOf[T]) } final class IntArray(arr: Array[Int]) extends AbsArray[Int] { def apply(idx: Int): Int = applyInt(idx) def update(idx: Int, elem: Int) = updateInt(idx, elem) override def applyInt(idx: Int): Int = arr(idx) override def updateInt(idx: Int, elem: Int) = arr(idx) = elem def length: Int = arr.length } final class ArraySeq[T](arr: Array[T]) extends AbsArray[T] { def apply(idx: Int): T = arr(idx) def update(idx: Int, elem: T) = arr(idx) = elem def length: Int = arr.length } class SpecArray[@specialized T](arr: Array[T]) extends AbsArray[T] { def apply(idx: Int): T = arr(idx) def update(idx: Int, elem: T) = arr(idx) = elem def length: Int = arr.length } abstract class Test { def sum(): Int def modify(i: Int): Unit def run(): Unit = { var s = 0 for (i <- 1 to 1000000) { s += sum() modify(i) } println(s) } } class ScalaSpecTest extends Test { val arr = new IntArray(new Array[Int](1000)) def sum(): Int = { var acc = 0 var i = 0 while (i < arr.length) { acc = acc + arr.applyInt(i); i += 1 } acc } def modify(j: Int) = { val base = j * 100 % 1000 var i = 0 while (i < 100) { arr.updateInt(i + base, arr.applyInt(i + base) + 1) i += 1 } } } class ScalaSpec2Test extends Test { val arr: AbsArray[Int] = new IntArray(new Array[Int](1000)) def sum(): Int = { var acc = 0 var i = 0 while (i < arr.length) { acc = acc + arr.applyInt(i); i += 1 } acc } def modify(j: Int) = { val base = j * 100 % 1000 var i = 0 while (i < 100) { arr.updateInt(i + base, arr.applyInt(i + base) + 1) i += 1 } } } class ScalaWrapTest extends Test { val arr: AbsArray[Int] = new ArraySeq(new Array[Int](1000)) def sum(): Int = { var acc = 0 var i = 0 while (i < arr.length) { acc = acc + arr.applyInt(i); i += 1 } acc } def modify(j: Int) = { val base = j * 100 % 1000 var i = 0 while (i < 100) { arr.updateInt(i + base, arr.applyInt(i + base) + 1) i += 1 } } } class ScalaGenTest extends Test { val arr: AbsArray[Integer] = new ArraySeq(new Array[Integer](1000)) for (i <- 0 until arr.length) arr(i) = new Integer(0) def sum(): Int = { var acc = 0 var i = 0 while (i < arr.length) { acc = acc + arr.apply(i).intValue; i += 1 } acc } def modify(j: Int) = { val base = j * 100 % 1000 var i = 0 while (i < 100) { arr.update(i + base, new Integer(arr.apply(i + base).intValue + 1)) i += 1 } } } class JavaTest extends Test { val arr = new Array[Int](1000) def sum(): Int = { var acc = 0 var i = 0 while (i < arr.length) { acc = acc + arr(i); i += 1 } acc } def modify(j: Int) = { val base = j * 100 % 1000 var i = 0 while (i < 100) { arr(i + base) += 1 i += 1 } } } /** Specialized array test. */ class ScalaSpec3Test extends Test { val arr: SpecArray[Int] = new SpecArray(new Array[Int](1000)) def sum(): Int = { var acc = 0 var i = 0 while (i < arr.length) { acc = acc + arr(i); i += 1 } acc } def modify(j: Int) = { val base = j * 100 % 1000 var i = 0 while (i < 100) { arr(i + base) = arr(i + base) + 1 i += 1 } } } object TestRunner { (new JavaTest).run() (new ScalaSpecTest).run() (new ScalaSpec2Test).run() (new ScalaGenTest).run() (new ScalaWrapTest).run() (new ScalaSpec3Test).run() }