Is there a way to create objects array without fil...
# getting-started
j
Is there a way to create objects array without filling and manually fill it afterwards? Like, in my case I have something like this, but it's a bit ugly, and it does unnecessary filling array with
null
Copy code
val tempLines = Array<IntArray?>(width + height) { null } as Array<IntArray>
            for (x in 0 until width) {
                tempLines[x] = IntArray(height) { y -> x + y * width }
            }
            for (y in 0 until height) {
                tempLines[y + width] = IntArray(width) { x -> x + y * width }
            }
Creating two arrays and concatenating them via
+
is not an option, because performance is very critical
k
A slightly shorter version of your first line is:
Copy code
val tempLines = arrayOfNulls<IntArray>(width + height) as Array<IntArray>
But why not initialize in one go?
Copy code
val tempLines = Array(width + height) {
    if (it < width)
        IntArray(height) { y -> it + y * width }
    else
        IntArray(width) { x -> x + it * width }
}
1
j
I don't really like that
if(it < width)
check called on every loop step, tho maybe performance hit is negligible enough for me to use it
e
the initial "filling the array with nulls" always happens automatically on JVM; the Array pseudo-constructor hides that from you
j
Hmm, I will check out
requireNotNull
but I doubt it doesn't have performance implications
@ephemient looking at decompilled bytecode,
Array(length){null}
actually have a dedicated loop upon creation, setting every element to null
arrayOfNulls
doesn't have this issue as far as I see
e
it's not visible in the bytecode
the JVM will never hand you an uninitialized array - it's always pre-filled
j
image.png,image.png
Even looking at bytecode, fun1 have significantly more operations than fun2
e
that's not what I'm talking about
j
I know that I get array of nulls in both cases, but in
fun1
there is an extra loop, writing `null`s into array of `null`s
e
what I mean is that the
Array
constructor is effectively
Copy code
fun <T> Array(size: Int, init: (Int) -> T) =
    arrayOfNulls<T>(size).apply {
        for (i in 0 until size) {
            set(i, init(i))
        }
    } as Array<T>
although it's hard-wired in the compiler
j
Ah, got it
e
if you really want performance, I suspect it would be better not to use 2-D arrays. use a flat IntArray and manage your own indexing
j
I already do that for main map itself, but I can't really do that for lines, because they can be varying length. Even in this very consistent example, we have vertical and horizontal lines, which have different lengths
Aka, on different fields lines will be generated in different ways, and I can make no assumptions about them
Thank you for help!
e
it looks like you have a width*height array + a height*width array concatenated together
that is totally doable in a one or two flat arrays