[MUSIC PLAYING]
YI YANG: Hello there.
My name is Yi.
I'm a software engineer on the Android Studio team.
In this session, I'll share how to accurately measure
your app's performance using profileable builds.
When an app has poor performance such as animation jank,
frozen frames, and high memory usage,
it negatively impacts user experience.
And to fix these performance issues,
we first need the right tools to measure them.
This is where profiling comes in.
Profiling helps you find where CPU cycles and memory are spent
at the time of inspection.
Android Studio offers a suite of profilers
to help with the inspection.
When working with profilers, there
are some things to keep in mind.
Historically, profiling in an Android app
requires a debug build.
As Android developers, you are most likely
familiar with the debug and release
built variants, which are automatically
created by Android Studio.
The debug build allows you to use features
useful for development, like Apply Changes,
working with the Debugger or the Database Inspector.
In addition, it also enables profiling tools
to inspect the state of a running app
unavailable to the release build.
Under the hood, the debug build sets
the debuggable flag in the Android manifest to true.
While useful, the debug build is meant
to provide more information at the cost of performance.
That's because when debuggable is true,
a lot of compiler optimizations are turned off.
Let me show you the performance difference.
To visualize the frame rendering time,
I turn on profile GPU rendering in Developer Options.
Each vertical bar on the bottom of the screen
represents how long each frame takes to render.
So the shorter these bars are, the smoother the animation is.
Here's a screen recording showing you
the same app running on the same device.
The left-hand side is on the debug
build, the right-hand side a release build.
As you can see, the debug version
has more stuttering frames, also known as UI jank.
This means when you profile the debug build,
you may see timing measurements significantly
different from what your users see in the release build.
And you may end up optimizing something that
is not a problem in the end.
To address that issue, the Android platform
introduced a tag called profileable.
It enables many profiling tools that measure timing information
without the performance overhead of the debug build.
Profileable is available on devices
running Android 10 or higher.
Let's look at another screen recording.
This time, the left side shows a profileable release app
and the right side an unmodified release app.
There's little performance difference between the two.
With the profileable, you can now
measure the timing information much more accurately
than the debug build.
The feature is designed to be used in production, where
app security is paramount.
So we decided to only support profiling features
such as callstack sampling and system trace,
where timing measurement is critical.
The Memory Profiler only supports native memory
profiling.
The Energy Profiler and Event Timeline are not supported.
All these restrictions are put in place
to keep your app's data safe.
Now that you know what the profileable tag does,
let me show you how to use it.
There are two options--
automatically and manually.
First, automatically with Android Studio--
with Android Studio Flamingo and Android Gradle plug-in 8.0,
all you need to do is just select
the option from the profile dropdown
menu in the run toolbar, profile with low overhead.
Then Android Studio will automatically
build a profileable app of your current
build type and attach the profiler.
It works for any build type.
But we highly recommend you to profile a release build,
which is what your users see.
Notice when a profileable app has been profiled,
there's a visual indicator along with a banner message.
Only the CPU and Memory Profiler is available,
as I mentioned earlier.
And in the Memory Profiler, only the native allocation recording
feature is available due to security reasons.
This feature is great for simplifying
the process of local profiling, but it only
applies when you profile with Android Studio.
Therefore, it can still be beneficial to manually
configure your app in case you want to diagnose performance
issues in production, or if you're not
ready to use the latest Android Studio or Android
Gradle plugin yet.
So here's the second option--
manual configuration.
It takes four steps to manually enable profileable.
First, add this line to our AndroidManifest.xml.
Then switch to the release build type or any build
type that's not debuggable.
Third step-- make sure you have a signing key configured.
To prevent compromising your release signing key,
you can temporarily use your debug signing key
or configure a new key just for profiling.
Finally, build and run the app on a device
running Android 10 or higher.
And now you have a profileable app.
You can then attach the Android Studio profiler
by launching the profiler to a window
and selecting the app process from the dropdown list.
Many of you may wonder if it is safe to leave
the profileable manifest tag in production.
And the answer is yes.
This tag is designed to be usable in release builds
to enable local profiling.
No memory data is readable by the host profiling
tools and the shell process.
Only stack traces are readable, which
are typically obfuscated or lacking
symbols in release builds.
And that's it.
We've shown you that profiling the debug build
may skew performance.
And therefore, it's better to analyze
the release build with the profileable tag enabled.
In summary, the release build is for production.
A profileable release build is ideal for profiling CPU timing.
And the debug build is for the other tasks.
To learn more about profileable builds,
start by reading the documentation
in the Android Manifest section in the Android Studio guides.
You can also find these links in the description below.
With these tools provided by the Android team,
we hope you can make your app run faster and smoother.
Thank you.
[MUSIC PLAYING]