`rememberUpdatedState` writes its state twice on i...
# compose-android
u
rememberUpdatedState
writes its state twice on initial composition. I wonder if it is possible to avoid this, and if so, under what circumstances it could make sense.
Copy code
fun <T> rememberUpdatedState(newValue: T): State<T> = remember {
    mutableStateOf(newValue)
}.apply { value = newValue }
For example, when there are several
rememberUpdateState
usages in one place, say 6 or 7 or 13, one might combine them into a single state holder object. Maybe in this case an optimization like that could make more sense?
Copy code
class Holder(
    prop1: Type1,
    prop2: Type2,
    //...
    prop7: Type7
) {
    var prop1 by mutableStateOf(prop1)
    var prop2 by mutableStateOf(prop2)
    //...
    var prop7 by mutableStateOf(prop7)
}

val updatedState = remember { Holder(prop1, prop2, /*...*/, prop7) }.also {
    it.prop1 = prop1
    it.prop2 = prop2
    //...
    it.prop7 = prop7
}
I imagine if I used composer compiler plugin APIs directly then I could skip the extra assignments, for example like this:
if (!currentComposer.inserting) { it.prop1 = prop1 }
f
rememberUpdatedState
writes its state twice on initial composition
You mean the default value and then the assignment in
apply
? Why is that a problem? It's the same value
u
Performance concern
f
Do you observe any performance problems? What do you think is the problem? No additional recomposition or anything is triggered if you assign the same value to state. Especially if you assign it in the same snapshot
u
@Filip Wiesner my question is under what circumstances this could make sense. It's a question about performance optimization
f
I don't think the extra assignment is a problem under any circumstances 🙂
u
Thank you for your thought. My understanding is that the mere operation of writing to state is relatively expensive, for example compared to writing to a plain field. If it is the same value it may incur lesser total costs, but I imagine it could still be comparably pricey. I would like to find an answer that goes beyond conjecture.
s
Compose conflates changes anyway, so your observers of that state won't see a thing.
a
It makes sense only after you measure the performance of the extra writes and find that they are taking a considerable amount of time.
u
Thanks, I am hoping for someone from the compose compiler/runtime team to chime in with some basic insight before I spend a day on performance testing. @shikasd offered some numbers in a talk last year suggesting that reading state may be on the order of 2500 times the cost of reading a local variable. My assumption is that writing state, even the same value, would incur substantial overhead as well. The pattern from
rememberUpdatedState
's implementation has popped up for me in various different contexts. This is what triggers my interest in understanding the pattern's performance implications in general.
rememberUpdatedState
is focused on a single state, so optimization may not make much sense, but the scales might tip a different way when double writing, say, 13 states at once.
s
Fwiw, writing state is way cheaper than reading it
👍 1
u
Thanks, that's good to know. Can I even attempt to use
currentComposer.inserting
without my app code blowing up? If not then none of this really matters.
s
I don't think it is a serious concern here, but we welcome any kind of benchmarking in this area. Let me know if you see a significant difference with additional writes. About
inserting
, it should be fine to use it, changing this flag's behavior would blow up a lot of things internally
u
Thank you, I will plan to test this out sometime over the summer.