https://kotlinlang.org logo
Title
a

Ayfri

12/15/2021, 9:30 AM
Hi, what is the better between
data class Zone(x: IntRange, y: IntRange, z: IntRange)
and
data class Zone(x1: Int, y1: Int, z1: Int, x2: Int, y2: Int, z2: Int)
? And would it impact performances to use Ranges ? I only need like 50 zones maximum for my project
1️⃣ 4
m

Matteo Mirk

12/15/2021, 9:36 AM
first code for clarity, so definitely the former code, then measure the effective performance and eventually deal with it
1
r

Rob Elliot

12/15/2021, 9:36 AM
A good rule of thumb is: don't worry about performance until a) you have a genuine problem and b) you have automated a way to performance test it that will prove that one way is faster than another. Until you've got both of those, write the thing that is easiest to understand. In this case that's clearly 1.
8
m

Matteo Mirk

12/15/2021, 9:39 AM
The first code can be improved with better parameter names, since they aren’t just points but ranges; so maybe
xRange
or
xSpan
, etc. for example
a

Ayfri

12/15/2021, 9:43 AM
Nice explanation thanks !
y

Youssef Shoaib [MOD]

12/16/2021, 7:59 PM
If performance turns out to be crucial, there's still no need for #2. What you can do is this: (playground)
@JvmInline
value class MyIntRange private constructor(private val underlying: Long) {
    constructor(start: Int, end: Int) : this(packStartWithEnd(start, end))

    val start: Int
        get() = unpackStart(underlying)

    val end: Int
        get() = unpackEnd(underlying)
        
    fun copy(
        start: Int = this.start,
        end: Int = this.end
    ): MyIntRange =
        MyIntRange(start, end)

}

private fun packStartWithEnd(start: Int, end: Int): Long =
    (start.toLong() shl Int.SIZE_BITS) or (end.toLong() and 0xffffffffL)

private fun unpackStart(packed: Long): Int =
    (packed shr Int.SIZE_BITS).toInt()

private fun unpackEnd(packed: Long): Int =
    packed.toInt()

fun main(){
    // Poor man's unit tests
    val range = MyIntRange(20, 45)
    val newRange = range.copy(end = 42)
    println(range.start == 20)
    println(range.end == 45)
    println(newRange.start == 20)
    println(newRange.end == 42)
}
This doesn't sacrifice the conciseness of #1 nor does it sacrifice the performance of #2