Skip to content

Instantly share code, notes, and snippets.

@akisaarinen
Created December 16, 2011 21:05
Show Gist options
  • Save akisaarinen/1487975 to your computer and use it in GitHub Desktop.
Save akisaarinen/1487975 to your computer and use it in GitHub Desktop.
Vector (in math sense) speed test
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