Skip to content

Performance

Reflection Cache

ImmuKT needs to know how to get properties from a data class and how to create a new instance of the data class. It is expensive to get this information since it involves reflection. ImmuKT internally keeps a cache of this information for every class it worked with.

It might be a problem if your program creates new classes very often (for example loading classes dynamically from .jar files) If this is your use case, please file an issue!

Lazy Evaluation

By default, ImmuKT converts the draft data class (contains both the original data and the modifications) to the actual data class (a new instance of data class with all the modifications applied) only when that data class is first accessed.

For example:

import site.pegasis.immukt.DataClass
import site.pegasis.immukt.draft.DataDraftList

data class Person(val name: String, val age: Int) : DataClass {
    init {
        println("$name inited, $age")
    }
}

val list = listOf(
    Person("Pega", 18) // prints "Pega inited, 18"
)

val newList = DataDraftList.from(list).produceWith {
    it[0][Person::age] = 19
}
// type of newList is List<Person>
// **does not print anything!**

print(newList.size) // prints 1

newList[0].name
// **modified data class first accessed here**
// **prints "Pega inited, 19"**

To disable lazy evaluation, pass false to produceWith:

val newList = DataDraftList.from(list).produceWith(false) {
    it[0][Person::age] = 19
}
// prints "Pega inited, 19" immediately

Benchmarks

Benchmarks are performed on my 14' Macbook Pro with M1 Pro with Java 11: