Jumat, 15 Oktober 2010

Traceview War Story

Jika anda baru pertama kali berkunjung ke blog ini, Silakan kasih Komentar untuk artikel yang anda baca.

I fresh took my prototypal earnest look at Traceview, and it occurred to me, first, that there are probably a few another Android developers who haven’t used it and, second, that this is an possibleness to reproval sternly on digit of my selection subjects: action improvement and profiling. This is perhaps a lowercase taste Android-101; If you already undergo every most Traceview, you crapper kibosh here and go backwards to coding.

Making Apps Fast

Here’s a belief that I think I deal with most experienced developers: For any app that is modify moderately complex, you’re not sharp sufficiency to prognosticate what the andante parts are feat to be, because nobody is sharp sufficiency to prognosticate where cipher bottlenecks will invoke up.

So the sharp artefact to write a fast app is to build it in the simplest artefact that could mayhap work, avoiding egregiously-stupid thing same order-N-squared algorithms and doing I/O on the Android UI thread. Who knows, it strength be fast enough, and then you’re done!

If it isn’t fast enough, don’t guess why. Measure it and encounter out, using a profiler. Actually I’ve been famous to do this, when backed into a corner, using things same System.err.println("Entered at" + System.currentTimeMillis()); Fortunately, Android comes with a reasonably decorous profiler, so you don’t hit to intend grotesque same that.

Case Study: LifeSaver 2

I hit this lowercase programme in Android Market titled LifeSaver 2, the info are on my personal blog. At digit point, it reads the SMS and phone-call logs discover of the grouping and persists them in a JSON text enter on the SD card. Since this is category of slow, it shows a pleasant dynamic progress bar. It occurred to me to astonishment why it was category of andante to write a few hundred records into a text enter on a figure that, after all, has a rate processor.

Somebody who foolishly disregarded my advice above strength assume that the slowdown had to be due to the ContentProvider Cursor machinery datum the grouping logs, or imperfectness that, the overhead of writing to the SD card. A wiser mortal would instrument the cipher and encounter out. Let’s do that.

Turning On Tracing

I went into Saver.java and bracketed the cipher in its run() method same so:

open vacuum run() { android.os.Debug.startMethodTracing("lsd"); // ... method embody elided android.os.Debug.stopMethodTracing(); }

The prototypal call turns drawing on, the discussion "lsd" (stands for Life Saver Debug, of course) tells the grouping to put the analyse index in /sdcard/lsd.trace. Remember that doing this means you hit to add the WRITE_EXTERNAL_STORAGE authorisation so you crapper spend the analyse info; don‘t forget to vanish that before you ship.

[Update:] Android engineer missionary Ducrohet writes to remind me: “DDMS has a start/stop profiling fix in the ‘device view’. Upon clicking kibosh it launches TraceView with the analyse file. This is not as fine grained as putting start/stopMethodTracing in your cipher but crapper be quite useful. For VMs earlier than froyo, the authorisation is required as substantially (DDMS basically automate effort the analyse from the sd bill and saving it locally before occupation traceview). For Froyo+ VMs, the VM is able to send the analyse enter through the JDWP unification and the authorisation is not needed anymore (which is rattling useful).” Thanks, Xav!

Then you separate your app, then you double the production over to your computer, and blast up Traceview.

540> adb vantage /sdcard/lsd.trace541> traceview lsd

At this point, you will hit detected three things. First, motion drawing on rattling slows down your app. Second, the tracefile is big; in this case, 8.6M for a separate that took same quaternary seconds. Third, that traceview looks pretty cool.

The exerciser crossways the crowning exhibit the app’s threads and how they dealt discover the time; since the Nexus One is single-threaded CPU, they hit to take turns. Let’s zero in on digit 100-msec segment.

The crowning distinction is where my app cipher is streaming (the flushed portion is GC happening), the middle distinction is the UI arrange and the bursts of state are the ProgressBar updating, and I hit no intent what the ordinal thread, named HeapWorker, does, but it doesn’t seem a field presenter to the app’s runtime, so let’s cut it.

The bottom of the concealment is where the rattling interesting accumulation is; it shows which of your methods destroyed the time, and crapper be sorted in a bunch of assorted ways. Let’s zero in on the prototypal digit lines.

Translated into English, this tells us that the top-level turn exhausted 100% of the instance if you include everything it titled (well, yeah), but only 0.9% of the instance itself. The incoming distinction suddenly starts to intend actual interesting: java.io.PrintStream.println(Object) and whatever it calls are using 65.2% of the app’s time. This is the cipher that writes the JSON discover to the SD card. Right away, we undergo that apparently the duty of actuation the accumulation discover of the phone’s ContentProviders doesn’t seem to be rattling expensive; it’s the production that’s hurting.

Can we conclude that the app is restricted by the inactive write action of the SD card? Let’s drill down, which is finished in the most manifest point-and-click artefact imaginable.

Ooh, there’s a filthy surprise. Of course, println calls (in effect) toString() on every its arguments. It looks same motion the arguments to strings is taking over half the time, before it modify dispatches from println(Object) to println(String).

I’ll skip the step of drilling down into println(String) but it does suggest that yes, there is whatever andante I/O event there, to the SD card. But let’s look exclusive that String.valueOf() call.

There’s your respiration pistol. It turns discover that org.json.JSONObject.toString() is what we professional programmers call a, well, this is a family-friendly activeness so I won’t go there. You crapper poke around exclusive it, but it’s meet depressing.

What you crapper do, however, is sort every the routines by their “Exclusive” times, as in the sort of mainframe circles destroyed right there in the routine. Here are every of them that use 1% or more of the amount enforcement time.

There’s a lowercase taste of GC and Android framework View-wrangling stuff in there, but the display is submissive by org.jason and java.lang.StringBuilder code.

The Conclusion

The actual closing is that in the housing of this app, I actually don’t care most the performance. A individual runs it a noble amount of digit times, once on the old sound and once on the newborn phone, and it’s got lots of eye candy, so I meet don’t think there’s a problem.

If I did want to pace this up, it’s manifest what to do. First, either kibosh using JSON, or encounter a cheaper artefact to serialize it. Second, do fewer println() calls; glom the accumulation unitedly in digit big pilot and meet blast it discover with a azygos I/O call. But, and here’s the key point, if I’d guessed where the bottlenecks were, I’d hit been wrong, mostly.

Traceview is a pleasant tool, and if you don’t already undergo it, you owe it to yourself to see it.


Thanks
basyar.com

Tidak ada komentar:

Posting Komentar