is it okay to measure composition time like this?
# compose
t
is it okay to measure composition time like this?
a
Never use
System.currentTimeMillis()
to measure elapsed time. Use
System.nanoTime()
or
SystemClock.elapsedRealtime()
on Android.
c
Even then, there's a lot of stuff going on during recomposition that I don't think is executed then 🤔 I doubt this measures rendering time
a
Yeah this only measures the time of composition phase in the three phases.
t
Sure. am not trying to measure
doFrame
call here anyway. but what’s the issue with
currentTimeMillis
?
t
Thanks 🙇 updated
Copy code
@Composable
inline fun MeasureComposition(
    tag: String,
    content: @Composable () -> Unit
) {
    val timestamp = System.nanoTime()
    content()
    val diff = System.nanoTime() - timestamp
    println("$tag took for recomposition: ${diff / 1_000_000}ms")
}
m
You could use the
measureTime
functions in Kotlin: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.time/measure-time.html
y
What about hooking in with the tracing APIs the compose runtime tracing uses?
t
aah.. good idea.. but is it possible? 🤔
y
Maybe library restricted...
But must be public in the bytecode.
t
@Ben Trengrove [G] can you please confirm the feasibility ?
s
This method of tracking recomposition is fine, tracing does almost the same
You can also use
Composer.setTracer
to hook into tracing APIs, but that's going to override default tracing tracker
1
t
Cool. So
traceEventStart
will be called for each recomposition and if its shows my composable name like this, it means it got recomposed? What else we can do with this? how can i get more data? Can i get entire
doFrame
call time at the Runtime? ( I’d like to get the measure time as well).. (sorry for asking too many questions at once 😄 this API looks exciting 😬 )
s
It is doing exactly the same as the sample above, but wrapped with an interface 🙂
So you can trace when composable is run and duration of that call 🙂
m
I’m not sure if it fits your need, but you could also add a trace section to your composable and use
TraceSectionMetric
from Macrobenchmark.
t
@mlykotom but that’ll only appear in the
.trace
file right? I am trying to get those info at runtime
m
Yes, that's only in a trace :/
y
I haven't tried them, but remember seeing these APIs, for tracing particular blocks. Mainly because macrobenchmark added them. https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:benchmar[…]/PerfettoTrace.kt?q=androidx.benchmark.perfetto.PerfettoTrace Added experimental new APIs
PerfettoTrace.record {}
and
PerfettoTraceRule
to capture Perfetto traces (also known as System Traces) as part of a test, to inspect test behavior and performance.
i
I’d just like to call out the giant caveat that you will have substantial variability measuring like this even on the same device. For example, the core can be underclocked to preserve battery or due to thermals. If you’re just trying to get some really rough data or look for outliers in a release sample, it’s probably okay. If you want to measure performance so that you can make improvements and verify them, you definitely want to use Macrobenchmark.
k
I have used perfetto traces and macrobenchmark for wider picture of screen. Not able to understand how can we use these to measure performance of just single Composable. Say I’m building some variations of button, how can I get to know which one is performant? Place single button on blank surface and capture perfetto trace for that activity?
t
@Kshitij Patil You can use intent extra to have a different behaviours in an activity. Here’s an example, where am checking if Coil is better than native Image component. Hope this helps
👍 1
k
Thanks @theapache64, this is really helpful
👍 1
140 Views