[MUSIC PLAYING]
CARMEN JACKSON: Hey, everyone.
My name is Carmen, and I'm on the Android Performance Team.
And today I'm going to show you some examples of analyzing
performance using systrace.
Before I do, want to remind you that your app is not an island.
It's running on top of several layers.
You know, the phone hardware, the Android framework,
libraries that you're incorporating, AB tests.
So you might think you know what your code is doing.
But the reality might actually surprise you.
And this is where this systrace comes in.
So systrace is a tool that lets you collect precise timing
information about what's going on your device
and then visualize it.
It records down to the individual CPU time slice.
On the Android Performance Team, it's
the most important tool we have for debugging performance
issues.
Tim Murray and I have given some talks
about how to use systrace in the past.
And if you want to know more about that, Google for his I/O
talk.
But today I'm going to focus on showing you what kind of issues
you can find in your app when you use systrace.
So I took traces of three apps that I don't work on.
But I could still quickly find potential improvements
to their startup time.
So let's jump in.
With the first app, when I look at the trace,
three different activity starts jumped out at me right away.
There are a lot of reasons to use trampoline activities.
I see them a lot when developers are
trying to show a splash screen, or do a permissions check,
something like that.
But they definitely impact your launch time.
And depending on what you're trying to do,
there might be a better way.
So if you're trying to make a splash screen,
you could set up a special launch theme.
Or for permissions, you could refactor your code
so that you only open the separate activity
if you need to.
I don't know why this app has these activities.
And maybe there are critical.
But if they don't, that's a 160 millisecond opportunity.
In the same app, I also browse through the names of the views
being inflated by this app.
Based on the name of this highlighted view
in the second row, it looks like it's a drawer view.
Drawer views are always a bit of a conundrum.
Because they often have a lot of child views and they
take a long time to inflate.
But sometimes we need them immediately for UX reasons.
If this app can pull this inflate out
of the critical path of startup, they
could save 42 more milliseconds.
So this second app is following the pattern for app startups
that I would expect.
In the top level there's no extra activities or services
being started.
I dug in a little more, clicked on the views that
were being inflated, and the names of the widgets
that I could see matched up with what was visible
when the app started.
So far so good.
But then I saw this gap in activity
inside bind application that takes up 30 milliseconds.
When I click on that trace point,
I'll see that it's monitor contention.
And I get more information.
So monitor contention is another way of saying lock contention,
where the owner of the lock is the thread pool-3-thread-1.
So that's in the top row.
And so I scroll down.
And I did, in fact, see activity in pool-3-thread-1 during this
time.
And then it's given me a pointer to the stack.
So I wasn't familiar with Realm so I looked it up.
And it's like a mobile database library like SQL.
So the function names kind of make sense here.
And this one may or may not be something
that you can fix as an app developer.
Because you might need to coordinate
with the Realm library.
But if you had a monitor contention between two threads
that you wrote in your say map, it would look the same.
Either way this is another potential 30
millisecond opportunity for this app where
they could get a start up improvement by resolving
this lock contention.
In this app there are two activities being started.
But there is another potential improvement here, too.
You see that I included the thread name over
on the left in the screenshot.
This is the UI thread.
So if we scroll down and see what's
going on in the other threads in this app,
we can see these background threads running, CPU1, CPU1,
CPU2.
And it's awesome that the app developers
made background threads to do some of their work.
But there's a potential performance issue here
that jumps out at me as well.
Which is that these background threads are
doing a lot of blocking I/O.
So that's the orange sections in the CPU activity bars
on the trace.
They're kind of hard to see.
So you can see there's some I/O happening on all three
of these threads.
Now it turns out that on a lot of devices
we have to be concerned about I/O contention.
There's not necessarily more than one I/O channel
to use to access the disk at once.
So these background threads may actually
be slowing down the I/O requests from the UI thread.
So that section is highlighted down below, we scroll up,
we see the busy four 10 milliseconds.
It overlaps with these activity starts.
By viewing the thread time slices in aggregate,
we can see that in this section we spend 107 milliseconds
in blocking I/O. We could potentially
shorten this amount of time significantly if we
move that background activity to overlap with something else.
All I needed to do to collect these traces
was to clone the catapult git repo
and run the systrace command.
You can just open the output HTML file in your browser
and see everything that I showed you today.
And this barely scratches the surface
of what you can do with systrace.
I was able to identify these potential opportunities
in apps I don't work on using only the trace points provided
by the system.
When you look at a trace of your own app with the expertise
you already have, it's going to make 100 times more sense
to you.
And you can even add your own trace points
inside your app code so you can see
the context of what's running in your app from within the trace.
Thank you.
[MUSIC PLAYING]