1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
abstract class AbsArray[T] {
def apply(idx: Int): T
def update(idx: Int, elem: T)
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)
def run() {
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()
}
|