Pages

Monday, March 11, 2013

Using Traceview for better performance

As some of you might already know, I'm starting a series of posts on optimizing Android apps for my thesis. In this post here, I'm going to give quick preview of how to use Traceview and why it's a great tool to use.

TraceWhat?

What is Traceview and why should I use it? These are the two questions we're going to start with. According to the Android Developers website, Traceview is a graphical viewer for execution logs that you create by using the Debug class to log tracing information in your code. Traceview can help you debug your application and profile its performance.
Basically what it does is it shows you what part of your code is using the CPU a lot. So that already covers the 'what'-part, now let's continue to the why part.

Why should we be interested in knowing how much CPU-time my awesome method needs to run? It's all about performance. Performance is one of the most important topics to focus on, especially in mobile development.We all want our app to be the fastest in the whole Play Store, don't we? By using Traceview properly, we can get a nice graph, showing us what part of our code is slowing down the app the most. Once we know this, we know where to start looking for better performance and get our app running twice as fast. I'll show you in an example below.

Example

For this small example, I'm going to write a simple app that does nothing. Well, nothing interesting that is. This is the code I'm going to run in the doInBackground() method of an AsyncTask.


String result = "";

for(int i=0; i<1000; i++){

 String number = String.valueOf(i);

 result += number;

}

Basically, it just makes on really long String (012345678910111213...).

Now how are we going to make sure that Traceview checks this part of the code? Really simple. All we have to do is add the next two lines somewhere in the beginning and at the end of our code:

Debug.startMethodTracing("bonappetit");

//...

//OUR CODE COMES HERE

//...

Debug.stopMethodTracing();

This will create a file called bonappetit.trace on the SD card of the device. Everything that happens between those two lines of code will be recorded in that file. I've started tracing ath the beginning and the end of the doInBackground() method.
IMPORTANT NOTE: Don't forget to add the permission in the manifest for writing to the SD card!
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

If we open the DDMS perspective in Eclipse, we can have a look at the files on our plugged-in device (or emulator). Select the device on the left side, then go to 'File Explorer' and look into the sdcard-folder for the file. (Mine was under /storage/sdcard0/). Once selected we can click 'Pull a file from the device'. Save the file somewhere on your computer.
Next use your command prompt and go to the folder of your android-sdks. Continue into the tools-folder and type the command 'traceview' followed by the file we just pulled from the device.



If we have a look at the results, we notice that almost 27% of the time was spend on StringBuilder <init>.
In the upper right corner we can see that the whole process took about 800ms, so that's more than 200ms.
If we have a look at our code we can see that we are actually creating a new String object every time in the for-loop. This is why the app spends so much time on StringBuilder <init>.

Now how can we make this better? As a good developer, you should know that using new String objects for creating one long string, isn't a good idea. Java has a class called StringBuilder. Let's try to change our code a bit like this and run the Traceview tool again:

StringBuilder sb = new StringBuilder(4000);

for(int i=0; i<1000; i++){

 sb.append(String.valueOf(i));

}

String result = sb.toString();


If we look in the upper right corner again this time, we can see that the whole process now only took 332ms.
This is more than twice as fast. It is possible to speed this process up even more, but always ask yourself "Does it have to be faster?". Don't waste time on optimizing things that don't need further optimization!

This was an example of Java-optimization, but because Android = Java, I'll make a post on this sort of code optimization as well. Feel free to leave comments below.

Try this out, it could be a great tool for you to use!



source: www.parleys.com

2 comments:

  1. Nice!! Helpful Can you explain a little what all those markers for..... i mean on the first trace there is a green marker for main... but on the second one there's no green markers??

    ReplyDelete
    Replies
    1. sorry for this late reply. The green markers point to startGC() which means start the Garbage Collector. The garbage collector removes unused object from the memory. This is done in the first example, because I'm creating new String objects each time it runs through the loop. In the second example, I'm using only one object of String.

      Delete