Created
December 16, 2011 21:05
-
-
Save akisaarinen/1487975 to your computer and use it in GitHub Desktop.
Vector (in math sense) speed test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package vectortest | |
// ------------------------------------------------------------- | |
// Simplest possible implementation, no parameterization | |
// ------------------------------------------------------------- | |
class Pos2d(val x: Double, val y: Double) { | |
def +(that: Vec2d): Pos2d = { | |
Pos2d(x + that.x, y + that.y) | |
} | |
override def toString = "Pos2d(%.2f, %.2f)".format(x,y) | |
} | |
object Pos2d { | |
def apply(x: Double, y: Double) = new Pos2d(x,y) | |
} | |
class Vec2d(val x: Double, val y: Double) | |
object Vec2d { | |
def apply(x: Double, y: Double) = new Vec2d(x,y) | |
} | |
// ------------------------------------------------------------- | |
// Generic numeric types (implicit num: Numeric[T]) | |
// ------------------------------------------------------------- | |
class Pos2dNumeric[T](val x: T, val y: T)(implicit num: Numeric[T]) { | |
def +(that: Vec2dNumeric[T]) = | |
new Pos2dNumeric(num.plus(x, that.x), num.plus(y, that.y)) | |
override def toString = "Pos2d(%.2f, %.2f)".format(num.toDouble(x), num.toDouble(y)) | |
} | |
object Pos2dNumeric { | |
def apply[T](x: T, y: T)(implicit num: Numeric[T]) = new Pos2dNumeric(x, y) | |
} | |
class Vec2dNumeric[T](val x: T, val y: T)(implicit num: Numeric[T]) | |
object Vec2dNumeric { | |
def apply[T](x: T, y: T)(implicit num: Numeric[T]) = new Vec2dNumeric(x, y) | |
} | |
// ------------------------------------------------------------- | |
// Generalized size by storing items in a Vector[Double] | |
// ------------------------------------------------------------- | |
class GenPos(items: Vector[Double]) { | |
def +(that: GenVec): GenPos = { | |
new GenPos(items.zip(that.items).map { case (a,b) => a+b }) | |
} | |
override def toString = { | |
val dimension = items.size | |
val values = items.map(i => "%.2f".format(i)).mkString(", ") | |
"Pos%dd(%s)".format(dimension, values) | |
} | |
} | |
object GenPos { | |
def apply(n: Int)(xs: Double*): GenPos = { | |
//if (xs.size != n) sys.error("Wrong number of values") | |
new GenPos(Vector(xs: _*)) | |
} | |
} | |
class GenVec(val items: Vector[Double]) { | |
def size = items.size | |
} | |
object GenVec { | |
def apply(n: Int)(xs: Double*): GenVec = { | |
//if (xs.size != n) sys.error("Wrong number of values") | |
new GenVec(Vector(xs: _*)) | |
} | |
} | |
// ------------------------------------------------------------- | |
// 2d specialization of general-size vectors | |
// Still using Vector[Double] as the data storage | |
// ------------------------------------------------------------- | |
class GenPos2d(x: Double, y: Double) extends GenPos(Vector(x,y)) { | |
def +(that: GenVec2d): GenPos2d = { | |
new GenPos2d(x + that.x, y + that.y) | |
} | |
} | |
object GenPos2d { | |
def apply(x: Double, y: Double) = new GenPos2d(x, y) | |
} | |
class GenVec2d(val x: Double, val y: Double) extends GenVec(Vector(x,y)) | |
object GenVec2d { | |
def apply(x: Double, y: Double) = new GenVec2d(x, y) | |
} | |
// ------------------------------------------------------------- | |
// Testing method, run simple summing operations with all | |
// vector types. | |
// ------------------------------------------------------------- | |
object VectorSpeedTest { | |
def test = main(Array()) | |
def main(args: Array[String]) { | |
val numberOfOps = 10000000 | |
time("Vec2d: Simplest", () => { | |
val dir = Vec2d(1.23, 4.56) | |
var pos = Pos2d(3.0, 2.0) | |
for (i <- 0 until numberOfOps) { | |
pos += dir | |
} | |
printf("Result: %s ", pos) | |
}) | |
time("Vec2dNumeric: Parameterized numeric type", () => { | |
val dir = Vec2dNumeric(1.23, 4.56) | |
var pos = Pos2dNumeric(3.0, 2.0) | |
for (i <- 0 until numberOfOps) { | |
pos += dir | |
} | |
printf("Result: %s ", pos) | |
}) | |
time("GenVec2d: Generalized size (specialized implementation for 2D)", () => { | |
val dir = GenVec2d(1.23, 4.56) | |
var pos = GenPos2d(3.0, 2.0) | |
for (i <- 0 until numberOfOps) { | |
pos += dir | |
} | |
printf("Result: %s ", pos) | |
}) | |
time("GenVec: Generalized size (parameterized)", () => { | |
val dir = GenVec(2)(1.23, 4.56) | |
var pos = GenPos(2)(3.0, 2.0) | |
for (i <- 0 until numberOfOps) { | |
pos += dir | |
} | |
printf("Result: %s ", pos) | |
}) | |
} | |
private def time(desc: String, f: () => Unit) { | |
val start = System.currentTimeMillis() | |
f.apply | |
val duration = System.currentTimeMillis() - start | |
printf("[%.3fs] For %s\n", duration / 1000.0, desc) | |
duration | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment