Kotlin FloatArray setting adjacent elements


#1

Background: I’m setting up some arrays for OpenGL/WebGL in Kotlin.

I have a block of code that looks something like:


fun set_adj(fa: FloatArray, n: Int) {

    fa[n + 0] = 0f;
    fa[n + 1] = 1f;
    fa[n + 2] = 2f;
    fa[n + 3] = 3f;
    fa[n + 4] = 5f;
    fa[n + 5] = 5f;
    fa[n + 6] = 6f;
    fa[n + 7] = 7f;
    fa[n + 8] = 8f;

}

the 0f, 1f, 2f, …, 8f are fake – in practice they are simple expressions.

I don’t like the repetition of one set per line. Is there a way to do something like:

fa[n … n+8] = [0f, 1f, 2f, …, 8f]

In practiced this is a bit easier to read, as it allows me to group exprs for a single vertex together instead of spreading them over distinct lines.


#2

I don’t know any kotlin specific method to do this but you could use java’s System.arraycopy

fun main(args: Array<String>){
//sampleStart
val f = floatArrayOf(1f, 2f, 3f, 4f)
val insert = floatArrayOf(5f, 6f)
System.arraycopy(insert, 0, f, 1, 2)

f.forEach { println(it) }
//sampleEnd

This will however require you to create the insert array. So if this is part of your openGL code you call a lot, you might want to avoid it for performance. Although I don’t think it is that bad, your code above is obviously faster. You also might want to create your own utility function around this. Something like

fun FloatArray.update(startingPoing: Int, vararg newValeus: Float) ...

#3

Thanks for your suggestion / analysis. System.arraycopy is better than what I had in mind (copy via for loop).


#4

Much better indeed, it uses block memory copy instead of element by element copy, which is much faster.
The performance loss mentioned by @Wasabi375 could be compensated by creating injecting array once with maximum length and using only part of it.


#5

If performance of this function really is critical I am not sure whether using arraycopy is the right approach though as an additional array has to be allocated and needs to be handled by the gc. I think the original code would still be the most performant, although I guess this would need a lot of benchmarking to be sure and could vary from system to system.