Answer the question
In order to leave comments, you need to log in
How to properly cache object properties in kotlin?
There is an object (a cube for example). Its properties that are calculated (mass, volume and much more) are very often used (get()). But its main properties from which these derivables are considered (width, length, density) change very rarely.
Is there any syntax or class so that its calculated parameters are saved, and when the main ones are changed, the calculated ones are recalculated.
Answer the question
In order to leave comments, you need to log in
Are you sure that these calculations load your program? It’s just that the problem is that here, from which side you can’t approach, it will become much more complicated from adding such optimizations. If you need to work with some value many times, then the simplest solution is to store it in a local variable where necessary. Another simple solution could be a data class with immutable properties, and instead of changing values, creating a copy via copy. Here it is also worth asking whether your program is multi-threaded, and whether these properties are displayed somewhere in the UI.
If the question is purely academic, such as how in theory you can do exactly what you want, then look towards memoization or delegate properties. Through memoization, a function from an argument to a result with the same arguments will be calculated only once, the result is usually stored in a map. Then you can write these memoized functions according to the number of class properties that you want to cache, and when accessing the property, call the corresponding function in the gettere. The problem here is that in a map this is a mapping from one object to another, and a function can have several arguments. You will have to write data classes for each such case. On delegates, you can reward something like this
data class Box(var height: Int, var width: Int) {
val area by DependingCalculation(::height, ::width) {
println("Calculated")
height * width
}
}
class DependingCalculation<R>(private val dependencies: List<KProperty0<*>>, private val calculation: () -> R) {
private var prevValues = dependencies.map { it.get() }
private var cache = calculation()
operator fun getValue(thisRef: Any?, property: KProperty<*>): R {
val newValues = dependencies.map { it.get() }
return if (newValues == prevValues) {
cache
} else {
calculation().also {
prevValues = newValues
cache = it
}
}
}
constructor(vararg dependencies: KProperty0<*>, calculation: () -> R) : this(dependencies.asList(), calculation)
}
fun main() {
val box = Box(1, 2)
println(box.area)
println(box.area)
box.width = 4
println(box.area)
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question