Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a composition tracing sample #212

Closed
yschimke opened this issue Feb 9, 2023 · 18 comments
Closed

Add a composition tracing sample #212

yschimke opened this issue Feb 9, 2023 · 18 comments
Assignees

Comments

@yschimke
Copy link
Contributor

yschimke commented Feb 9, 2023

Add a composition tracing sample, particularly with macrobenchmark.

https://developer.android.com/jetpack/compose/performance/tracing

@keyboardsurfer
Copy link
Member

Passing this over to @bentrengrove for evaluation.

@bentrengrove
Copy link
Member

Are you after a sample that would show Composable functions in a macrobenchmark trace? I think if we just add the dependency to the macrobenchmark sample, it should work.

@ChrisCraik
Copy link
Contributor

ChrisCraik commented Feb 9, 2023

You also need to enable the flag that turns on composition tracing: https://developer.android.com/topic/performance/benchmarking/macrobenchmark-instrumentation-args#fulltracing

This is off by default for now since it doesn't support tracing during cold startups (which is being worked on), and because overhead was a concern (though several optimizations have landed since).

@bentrengrove
Copy link
Member

This sounds like it would be a good sample then! I can do this

@yschimke
Copy link
Contributor Author

Perfect. It mostly that.

But also a forcing function to see a proper project setup with the dependencies and proguard rules.

@yschimke
Copy link
Contributor Author

Contrary to https://developer.android.com/jetpack/compose/tooling/tracing

I don't think you need these in your app as a implementation dependency.

https://github.com/google/horologist/pull/1209/files

    add("benchmarkImplementation", libs.androidx.tracing.perfetto)
    add("benchmarkImplementation", libs.androidx.tracing.perfetto.binary)

@yschimke
Copy link
Contributor Author

This was a nice win of the composition tracing, showing composition counts

google/horologist#1299

MarqueeBenchmark_noMarquee
CanvasRecomposeCount   min    55.0,   median    55.0,   max    55.0
CanvasRecomposeDurMs   min     8.3,   median     8.3,   max     8.3

@DirajHS
Copy link

DirajHS commented Aug 22, 2023

@bentrengrove Any updates on adding composition tracing example? I tried adding the dependencies and enabled the required flags as per the documentation, but it is not working.
@yschimke I have added those perfetto tracing dependencies benchmarkImplementation, but the app is crashing as soon as opened. Did you face something similar? I don't have a watch to run those benchmarks, so tried to use the same setup on phone with nowinandroid app.

@yschimke
Copy link
Contributor Author

What is the stacktrace?

@DirajHS
Copy link

DirajHS commented Aug 22, 2023

What is the stacktrace?

@yschimke Here's the stacktrace:

FATAL EXCEPTION: main
                                                                                                    Process: com.google.samples.apps.nowinandroid.demo.benchmark, PID: 20835
                                                                                                    java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/tracing/perfetto/Tracing;
                                                                                                    	at androidx.compose.runtime.tracing.TracingInitializer$create$1.isTraceInProgress(Unknown Source:0)
                                                                                                    	at coil.util.-Contexts.isTraceInProgress(SourceFile:1)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(SourceFile:3)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(SourceFile:1)
                                                                                                    	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:7)
                                                                                                    	at okhttp3.CertificatePinner$check$1.invoke(SourceFile:92)
                                                                                                    	at okhttp3.CertificatePinner$check$1.invoke(SourceFile:8)
                                                                                                    	at okio.Utf8.observeDerivedStateRecalculations(SourceFile:43)
                                                                                                    	at androidx.compose.runtime.ComposerImpl.doCompose(SourceFile:129)
                                                                                                    	at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(SourceFile:1)
                                                                                                    	at androidx.compose.runtime.CompositionImpl.composeContent(SourceFile:19)
                                                                                                    	at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(SourceFile:39)
                                                                                                    	at androidx.compose.runtime.CompositionImpl.setContent(Unknown Source:10)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(SourceFile:11)
                                                                                                    	at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(Unknown Source:11)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition.setContent(Unknown Source:13)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Unknown Source:18)
                                                                                                    	at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(SourceFile:23)
                                                                                                    	at androidx.lifecycle.LifecycleRegistry.addObserver(SourceFile:107)
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(SourceFile:11)
                                                                                                    	at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(SourceFile:119)
                                                                                                    	at android.view.View.dispatchAttachedToWindow(View.java:20018)
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3589)
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3596)
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3596)
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3596)
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3596)
                                                                                                    	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2208)
                                                                                                    	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1873)
                                                                                                    	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8496)
                                                                                                    	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:986)
                                                                                                    	at android.view.Choreographer.doCallbacks(Choreographer.java:764)
                                                                                                    	at android.view.Choreographer.doFrame(Choreographer.java:699)
                                                                                                    	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:965)
                                                                                                    	at android.os.Handler.handleCallback(Handler.java:873)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                    	at android.os.Looper.loop(Looper.java:214)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:7073)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
                                                                                                    Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.tracing.perfetto.Tracing" on path: DexPathList[[zip file "/data/app/com.google.samples.apps.nowinandroid.demo.benchmark-nAbe9X37TJQHd9EsCgdfyw==/base.apk"],nativeLibraryDirectories=[/data/app/com.google.samples.apps.nowinandroid.demo.benchmark-nAbe9X37TJQHd9EsCgdfyw==/lib/arm64, /data/app/com.google.samples.apps.nowinandroid.demo.benchmark-nAbe9X37TJQHd9EsCgdfyw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/vendor/lib64]]
                                                                                                    	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
                                                                                                    	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
                                                                                                    	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
                                                                                                    	at androidx.compose.runtime.tracing.TracingInitializer$create$1.isTraceInProgress(Unknown Source:0) 
                                                                                                    	at coil.util.-Contexts.isTraceInProgress(SourceFile:1) 
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(SourceFile:3) 
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(SourceFile:1) 
                                                                                                    	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:7) 
                                                                                                    	at okhttp3.CertificatePinner$check$1.invoke(SourceFile:92) 
                                                                                                    	at okhttp3.CertificatePinner$check$1.invoke(SourceFile:8) 
                                                                                                    	at okio.Utf8.observeDerivedStateRecalculations(SourceFile:43) 
                                                                                                    	at androidx.compose.runtime.ComposerImpl.doCompose(SourceFile:129) 
                                                                                                    	at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(SourceFile:1) 
                                                                                                    	at androidx.compose.runtime.CompositionImpl.composeContent(SourceFile:19) 
                                                                                                    	at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(SourceFile:39) 
                                                                                                    	at androidx.compose.runtime.CompositionImpl.setContent(Unknown Source:10) 
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(SourceFile:11) 
                                                                                                    	at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(Unknown Source:11) 
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition.setContent(Unknown Source:13) 
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Unknown Source:18) 
                                                                                                    	at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(SourceFile:23) 
                                                                                                    	at androidx.lifecycle.LifecycleRegistry.addObserver(SourceFile:107) 
                                                                                                    	at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(SourceFile:11) 
                                                                                                    	at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(SourceFile:119) 
                                                                                                    	at android.view.View.dispatchAttachedToWindow(View.java:20018) 
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3589) 
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3596) 
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3596) 
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3596) 
                                                                                                    	at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3596) 
                                                                                                    	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2208) 
                                                                                                    	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1873) 
                                                                                                    	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8496) 
                                                                                                    	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:986) 
                                                                                                    	at android.view.Choreographer.doCallbacks(Choreographer.java:764) 
                                                                                                    	at android.view.Choreographer.doFrame(Choreographer.java:699) 
                                                                                                    	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:965) 
                                                                                                    	at android.os.Handler.handleCallback(Handler.java:873) 
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:99) 
                                                                                                    	at android.os.Looper.loop(Looper.java:214) 
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:7073) 
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964) 

I have done the set up similar to the horologist project which seems to be contrary to what the documentation says about adding the tracing dependencies. Shouldn't they be added into Macrobenchmark module and not in the app module? Here's my branch if you want to try it out.

@yschimke
Copy link
Contributor Author

I think the docs are wrong. I've added it to the app module and it works.

The section above for capturing for the command line also says add to the app. https://developer.android.com/jetpack/compose/tooling/tracing#terminal

@DirajHS
Copy link

DirajHS commented Aug 22, 2023

Now it's really confusing. I added in the app module and it fails with the error mentioned above. I wanted to explore the Compose traces from Macrobenchmark tests and having a sample for apps would surely help here. Not to mention that having a single source of truth would benefit everyone!

I have created a separate issue in horologist to reduce unnecessary noise here.

@mlykotom
Copy link
Contributor

Hm, this is what eng for tracing recommended doing for Macrobenchmark.
Could you pls mention the details in https://issuetracker.google.com/issues/286228781

@DirajHS
Copy link

DirajHS commented Aug 22, 2023

Yes, I tried the recommended approach as well and still it is not working. Maybe something is in the documentation?

@yschimke
Copy link
Contributor Author

It's temporarily broken with some workarounds https://issuetracker.google.com/issues/286228781

And I need to update the Horologist samples after this lands tomorrow.

@mlykotom
Copy link
Contributor

mlykotom commented Nov 24, 2023

All the issues with versions and compatibility issues should be resolved by now by using latest versions of the libraries.
I also added a sample on how to setup composition tracing in this sample #263.

Thanks for the report!

@yschimke
Copy link
Contributor Author

@mlykotom should this be closed? I'd expect a gradle file with androidx.benchmark.fullTracing.enable.

@mlykotom
Copy link
Contributor

I haven't added this to the gradle file as some benchmarks might not work properly.
Instead, I added a run configuration that is stored within the project, which uses the argument
https://github.com/android/performance-samples/pull/263/files#diff-49f04f884293f57bf255ab94f217650ec55ac63317df696b314826a3a5bd056dR10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants