kyonifer / koma

A scientific computing library for Kotlin. https://kyonifer.github.io/koma
Other
270 stars 23 forks source link

Optimized indexing of arrays #94

Closed peastman closed 5 years ago

peastman commented 5 years ago

This is my attempt at fixing #93. While I was at it, I also added support for negative indices in the places that didn't yet have it.

Here's the code I used to benchmark it.

val x = NDArray(1000, 1000, filler = { getRng().nextGaussian().toFloat() })
for (trial in 1..10) {
    var sum = 0f
    val time = measureNanoTime {
        for (i in 0 until 1000)
            for (j in 0 until 1000)
                sum += x[i, j]
    }
    println("$sum, $time")
}

With these changes, I'm getting a roughly 9x speedup.

You'll notice that I removed a lot of calls to functions that checked the ranges of indices. That's because the same checks are now done in wrapIndex(), so there's no need to do them twice. I did not remove the calls to checkLinearIndex(), but we could consider doing that too. It isn't strictly necessary, since the storage array is already bounds checked. The only benefit is that it produces a slightly nicer error message. It's up to you whether that justifies the (probably small) cost of doing the bounds check twice.