https://kotlinlang.org logo
#compose
Title
# compose
a

Anton Shilov

03/04/2022, 11:29 AM
Hello! In Android Views world creating new objects in
onDraw
callback is considered a bad practice. In compose official docs we see creating instances of Offset, Path, etc. in DrawScope. Is it going to be impacting draw performance the same way as in views? Or we shouldn't care about such things in compose world?
👍 1
🤔 2
f

Filip Wiesner

03/04/2022, 11:47 AM
Not sure about
Path
but
Offset
is inline (value) class so that shouldn't be a problem
a

ade

03/04/2022, 12:20 PM
I don't think so, because recomposition doesnt happen on every frame, and if it does you've got a larger problem...
a

Anton Shilov

03/04/2022, 12:35 PM
If you're running an animation it could recompose on every frame and become problematic 🤔
a

Albert Chang

03/04/2022, 2:07 PM
Firstly, many of these (e.g.
Offset
,
Color
) are inline classes, which are essentially primitive types, so there isn’t any object allocations when using these classes. Secondly, that rule was proposed in the early years of Android, when it was still using Dalvik. ART is much better in this respect, and the performance of mobile chips has also improved a lot. Generally I don’t think this should be a big problem now. You can start to think about optimization when you actually see some performance issues.
a

Adam Powell

03/04/2022, 2:13 PM
All of the above is true. 🙂 ART and hardware have improved but putting pressure on the GC when you don't need to comes at a cost. In particular, on modern versions of ART the GC runs concurrently without the kinds of stop the world pauses you might be used to, but the trade-off is that while it's running, field reads involve full memory barriers, making all of the rest of your code on other threads run slower.
today i learned 3
❤️ 2
It's not free on desktop JVM either, but the characteristics are different
If we didn't worry about it at all then we wouldn't have bothered making the classes mentioned above inline. You'll see that in some very frequent code paths we also make sure to use O(1) indexed collection classes and forEach variants that avoid creating iterators.
👍🏼 1
👍 1
All that said, we've done this in the deeper compose internals so that in the common case, you don't have to go this far yourself in your own code unless you've measured a problem. Hardware and software have gotten better here. Keep it in mind, don't be unnecessarily wasteful, but don't tie your code completely in knots for something you haven't measured either.
💯 3
👍🏼 1
👍 2
Modifier.drawWithCache
is a good example of an API designed for helping you with this; you get an outer block for creating things you might reuse over time and an inner block for drawing using those same object instances
👍 1
f

Filip Wiesner

03/04/2022, 2:21 PM
we've done this in the deeper compose internals so that in the common case, you don't have to go this far yourself
Same reasoning as with enums in the "old days" (enums being represented with Integers instead of an actual enum)
a

Adam Powell

03/04/2022, 2:22 PM
Eh, kinda. 🙂 With the direction Kotlin took with exhaustive when around enums it's a really good thing Android mostly didn't use them, since exhaustive when means adding a new enum value is both binary and source breaking, whereas in plenty of cases with Java you can get away with it
And if you have thousands of them, they really do add up in terms of overhead unless you have a whole-program shrinker like r8 eliminate them and reduce them to primitives. Can't do that across a dynamically linked API boundary, at least not yet.
Avoiding the exhaustive when gotcha and being able to compatibly add new values to a type is why compose uses inline value classes for a lot of things instead of enums
f

Filip Wiesner

03/04/2022, 2:26 PM
Fair enough 👌 Thanks for the explanation
👍 1
a

Anton Shilov

03/04/2022, 3:46 PM
Thank you for the detailed explanation Adam 🙏
👍 1
2 Views