fork download
class Test(var x: Float, var y: Float) {
	@inline final def :=(x: Float, y: Float) = {
		this.x = x
		this.y = y
	}
	@inline final def :=(o: Test) = { //reassign from arg "o"
		x = o.x
		y = o.y
	}
	@inline final def :=(of: (Test) => Unit) = { //apply mutating function "of"
		of(this)
	}
	@inline final def something_m = { //just an example of mutating function that does something
		x = 42
	}
	override def toString() = x.toString() + ", " + y.toString()
}

object Benchmark {
	@inline final def benchmark(name: String, fun: () => Any) = {
		val t1 = System.currentTimeMillis()
		val res = fun()
		val t2 = System.currentTimeMillis()
		name + ": " + (t2 - t1).toFloat / 1000 + "sec; Result:" + res.toString()
	}
	val tmp = new Test(0, 0)
	@inline final def calc_something_for_reassign(a: Float, b: Float) = { //Assigns result to temporary object and exposes it (it's also dangerous)
		tmp := (a, b)
		tmp.something_m
		tmp
	}
	@inline final def calc_something_for_forwarding(a: Float, b: Float) = { //Creates a function that modifies its argument to the result
		(result: Test) =>
			{
				result := (a, b)
				result.something_m
			}
	}

	@inline final def run_a(spins: Int) = {
		val x = 2f
		val y = 3f
		benchmark("reassignment", () => {
			val v = new Test(x, y)
			var i = spins
			while (i > 0) {
				i -= 1
				v := calc_something_for_reassign(v.x, v.y) //Calculates temporary value and assigns it to `v`
			}
			v
		})
	}

	@inline final def run_b(spins: Int) = {
		val x = 2f
		val y = 3f
		benchmark("forwarding", () => {
			val v = new Test(x, y)
			var i = spins
			while (i > 0) {
				i -= 1
				v := calc_something_for_forwarding(v.x, v.y) //Forwards `v` to mutating function created in right-hand side
			}
			v
		})
	}
}

object Main {
	def main(args: Array[String]) {
		println(Benchmark.run_a(Int.MaxValue/100))
		println(Benchmark.run_b(Int.MaxValue/100))
		println(Benchmark.run_b(Int.MaxValue/100))
		println(Benchmark.run_a(Int.MaxValue/100))
	}
}
Success #stdin #stdout 0.95s 247424KB
stdin
Standard input is empty
stdout
reassignment: 0.091sec; Result:42.0, 3.0
forwarding: 0.272sec; Result:42.0, 3.0
forwarding: 0.241sec; Result:42.0, 3.0
reassignment: 0.092sec; Result:42.0, 3.0