https://kotlinlang.org logo
#getting-started
Title
# getting-started
j

juh juh

08/01/2022, 8:26 PM
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

Klitos Kyriacou

08/01/2022, 8:45 PM
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

juh juh

08/01/2022, 9:00 PM
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

ephemient

08/01/2022, 9:01 PM
the initial "filling the array with nulls" always happens automatically on JVM; the Array pseudo-constructor hides that from you
j

juh juh

08/01/2022, 9:02 PM
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

ephemient

08/01/2022, 9:03 PM
it's not visible in the bytecode
the JVM will never hand you an uninitialized array - it's always pre-filled
j

juh juh

08/01/2022, 9:05 PM
image.png,image.png
Even looking at bytecode, fun1 have significantly more operations than fun2
e

ephemient

08/01/2022, 9:06 PM
that's not what I'm talking about
j

juh juh

08/01/2022, 9:07 PM
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

ephemient

08/01/2022, 9:09 PM
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

juh juh

08/01/2022, 9:11 PM
Ah, got it
e

ephemient

08/01/2022, 9:11 PM
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

juh juh

08/01/2022, 9:13 PM
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

ephemient

08/01/2022, 9:17 PM
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
2 Views