I played around a bit with Lelands Countdown (<htt...
# compose
p
I played around a bit with Lelands Countdown (https://github.com/lelandrichardson/compose-dogfooding/tree/main/Countdown) and noticed that the performance of such a simple animation was not really that great (turned on the HWUI bars overlay) even on a High-End Device (Galaxy S21). For some reason these bars look better when I touch the screen vs when I don’t. Even when there is no pointerInput Modifier added for some reason the performance is better when I touch the screen anywhere 😮. Is this expected or is there anything I can do to improve it? (Video + Code in 🧵 )
🧵 1
😨 1
r
How about spawn CountDownTimer tick on background thread?
y
The s21 has an adaptive display feature (default on) to lower the screen refresh rate when "idle", not sure how it works exactly, but maybe it's related?
👍 1
p
How about spawn CountDownTimer tick on background thread?
Pretty sure everything is already happening on a background thread (Dispatchers.Default) and not on the main thread
The s21 has an adaptive display feature (default on) to lower the screen refresh rate when “idle”, not sure how it works exactly, but maybe it’s related?
Good point, but it’s the same on the Galaxy S10 😂 And the bars are also way higher ( and I would still consider this device rather high-end 😮 )
m
It’s very strange, I’ve seen other countdown apps without any lag. Mine has a waves effect that continuously moves in both horizontal and vertical directions and it doesn’t lag. Anyway about the better performance you get while touching the UI, as as far as I know the processor will swing into full gear the moment you touch the screen to keep input lag to a minimum since Android 4.1
p
I mean it’s not visually lagging on such a high-end device, but still these “GPU-bars” are quite high and probably means that lower end devices would would have dropped-frames. How does it look like when you enable them on your animation? (its in dev settings > Profile HWUI rendering)
m
Yeah, I was referring exactly to these gpu bars as an indicator of the performance. here is mine, you can see the app in action on twitter https://twitter.com/manueldidonna/status/1369333742129606657?s=19
p
That looks way more reasonable 😮 How are you drawing the Waves / what is driving the timer? Looks awesome btw!
❤️ 1
m
I've used a shader that I scale and translate on each frame. I've also tried to implement the same animation with a Path and the performance was still good. Try to test that app with a release build
The timer is driven by a custom flow that tries to emit in according to the app frames (like the Animatable class). Maybe the CountdownTimer emits too often 🤔
p
It’s the same when the timer only emits once per second 😄 Just less bars are drawn (on the x-axis), but the height does not change much. It’s probably more the fact that around 120 lines are drawn with
onDrawBehind
:S
m
I think we should tag @Leland Richardson [G] to notify him about the existence of this thread
s
On older devices like motorola G4 Android N. All the compose official samples and this App is pretty unusable for me.
l
👋 thanks for the ping. i haven’t looked into the performance of this example very much. i’d expect it to do pretty well but there is a lot going on in a single draw call (120 lines as mentioned) i might play around with it to try making the wheel its own layer to see if that improves anything. There’s also the difference of debug vs release which with compose is going to be somewhat significant. On a Pixel 2, i found this to be the difference between the two apps (after letting the JIT settle down on both):
the debug vs release difference is a combination of things, some of which are more significant in compose land: • lots of inlining done from r8 • no live literals
i could investigate more and profile the app and see if there were any low hanging fruit i saw if folks were interested
this app was mostly explicit canvas drawing which is sort of new for me and i don’t have a good intuition for what performance to expect for things like that
the video from patrick looks quite a bit worse, though i’m not sure why. it could be that the video was taken while the JIT was still running? we have some investigations under way right now to improve this as it impacts compose much more significantly than views because it is unbundled
for comparison, this is what it looked like for me right as app loaded (while code was likely still jitting)
😰 1
oh cool, @patrick sent me a change to the code which made some nice improvements
you can see once the jit settles down the bulk of the work seems to be in GL commands. i wonder if there’s a more efficient way for me to do that. since i’m drawing 3 “wheels” of tickmarks, i suspect if i broke each one into its own layer then it would just need to update one per frame, which might be like a 66% improvement there
🤔 1
s
@Shakil Karim Build application in release mode with R8 optimizations enabled(
minifyEnabled true
in gradle script). Also charge your phone, system's scheduler can drop cpu/gpu clocks to the minimum for economy energy.
@patrick This is the default behavior on Samsung devices. They have optimizations to reduce the refresh rate of the Window Composer when a user is not touching the screen. This works across all applications. LG, HTC and other vendors had similar optimizations with 60Hz displays.