[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]
