Hullaballoonatic
09/26/2021, 9:30 PMhho
09/26/2021, 11:08 PMpackage hho.bench
class Vector(private val data: List<Double>) : List<Double> by data {
	fun innerProductFunctional(other: Vector): Double {
		assert(size == other.size) { "different length" }
		return zip(other) { a, b -> a * b }.sum()
	}
	fun innerProductImperative(other: Vector): Double {
		assert(size == other.size) { "different length" }
		var result = 0.0
		for (i in indices) {
			result += this[i] * other[i]
		}
		return result
	}
}hho
09/26/2021, 11:09 PMpackage hho.bench
import org.openjdk.jmh.annotations.Benchmark
import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State
@State(Scope.Thread)
open class MyBenchmark {
    val a = Vector(listOf(1.0, 2.0, 3.0))
    val b = Vector(listOf(4.0, 5.0, 6.0))
    @Benchmark
    fun testFunctional(): Double = a.innerProductFunctional(b)
    @Benchmark
    fun testImperative(): Double = a.innerProductImperative(b)
}Hullaballoonatic
09/26/2021, 11:09 PMHullaballoonatic
09/26/2021, 11:10 PMhho
09/26/2021, 11:10 PMBenchmark                    Mode  Cnt          Score        Error  Units
MyBenchmark.testFunctional  thrpt    5   29454305.213 ± 424739.023  ops/s
MyBenchmark.testImperative  thrpt    5  105334475.867 ± 908519.089  ops/sHullaballoonatic
09/26/2021, 11:10 PMinterface Vector: Iterable<Double> {
    val size: Int
    val indices: Iterable<Int>
    operator fun get(i: Int): Double
    operator fun unaryMinus(): Vector
    operator fun plus(other: Vector): Vector
    operator fun minus(other: Vector): Vector
    operator fun times(other: Double): Vector
    operator fun div(other: Double): Vector
    operator fun times(other: Vector): Double
    val squareMagnitude: Double
    val magnitude: Double
    companion object {
        fun from(elements: DoubleArray): Vector = object : Vector {
            override val size = elements.size
            override val indices get() = elements.indices
            override fun iterator() = elements.iterator()
            override fun get(i: Int): Double = elements[i]
            override fun unaryMinus(): Vector = Vector(size) { i -> -get(i) }
            override fun plus(other: Vector): Vector {
                assert(size == other.size) { "Cannot sum vectors of differing sizes: $size != ${other.size}" }
                return invoke(size) { i -> this[i] + other[i] }
            }
            override fun minus(other: Vector): Vector {
                assert(size == other.size) { "Cannot subtract vectors of differing sizes: $size != ${other.size}" }
                return invoke(size) { i -> this[i] - other[i] }
            }
            override fun times(other: Double): Vector {
                return invoke(size) { i -> this[i] * other }
            }
            override fun div(other: Double): Vector {
                return invoke(size) { i -> this[i] / other }
            }
            override fun times(other: Vector): Double {
                assert(size == other.size) { "Cannot inner product vectors of differing sizes: $size != ${other.size}" }
                return zip(other) { a, b -> a * b }.sum()
            }
            override val squareMagnitude: Double by lazy { sumOf { it * it } }
            override val magnitude: Double by lazy { sqrt(squareMagnitude) }
            override fun toString() = joinToString(prefix = "(", postfix = ")")
        }
        fun of(vararg elements: Double) = from(elements)
        fun of(vararg elements: Number) = elements.map(Number::toDouble).toVector()
        operator fun invoke(size: Int, generator: (i: Int) -> Double): Vector = from(DoubleArray(size, generator))
    }
}Hullaballoonatic
09/26/2021, 11:18 PMFudge
09/27/2021, 9:20 AMHullaballoonatic
09/29/2021, 11:14 PM