
In his book
, Paul Graham states: “The execution efficiency gap between different programming languages is becoming increasingly large, so profilers are becoming more important. Currently, performance profiling is not receiving enough attention. Many people still believe that the key to improving program running speed is developing compilers that can generate faster code. The gap between code efficiency and machine performance is continuously increasing, and we will increasingly clearly see that the key to improving application software running speed is having a good performance profiler to guide program development.”
By Paul Graham — Hackers and Painters
Search for “Android optimization tools” and you’ll find plenty of articles. Many repeat the same material or go straight to instructions without explaining how the tools fit together. It is easy to come away thinking one tool can solve everything. Our team’s experience says otherwise: there is no silver bullet. Tools change, and familiar problems return in new forms. You still need to understand what is happening underneath.
We’ll start with the data we collect, how we collect it, and how we analyze it. Then we’ll look at Google’s traditional “big three” performance tools. We want you to understand the measurements as well as the tools, and save yourself some of the detours others have already taken.
Technical review — 2026-10-14: This article was published in January 2022. The Systrace and Studio screenshots are historical; current entry points and evidence limits are updated below. The three tools discussed are Systrace, Perfetto, and Android Studio Profiler, not a required sequence for every performance problem.
For current investigations, combine system tracing with repeatable measurement and field signals. FrameTimeline requires Android 12 / API 31 or later and a recording that includes its data. Use Macrobenchmark metrics such as StartupTimingMetric and FrameTimingMetric to compare controlled scenarios. Baseline Profiles and Startup Profiles are optimization inputs, not measurements or proof of improvement. Android vitals provides Google Play field signals from eligible, opted-in devices, not complete coverage of all users or every rendering path. Supplement it with telemetry appropriate to the product.
1 Observable Technologies in Performance Profiling
- Was this operation actually executed? How long did execution take?
- Why is there such a huge difference between two versions?
- What operations is the system executing when CPU usage becomes high?
- Why did startup speed become slower?
- Why does this page always stutter for a moment?
You’ve probably heard these questions from colleagues or your boss more than once. You get the logs, search for familiar keywords, and try to piece together what happened. Something is missing, so you add more logging and reproduce the problem again. It takes time, and other people’s time too. Isn’t there a better way to spend that effort—more time solving the problem, less time repeating the same manual work?
Yes—otherwise there wouldn’t be much point in this article. This is where observability comes in.
Observability uses recorded runtime information to help explain complex systems. Choose detail according to the question: collecting more data can add overhead without improving the explanation.
Static checks and code reviews cannot catch every problem. Some only show up when the software runs, even in an automated test. Once that happens, you still need to work out what the program did. Good observability makes that job easier. That is why we see it as part of a team’s basic engineering setup, rather than something to bolt on after a failure.
Reading code alone can make it hard to follow a complex system, especially when several components interact. Runtime observations let you see those interactions, investigate failures, and look for bottlenecks. Building that view takes work across the system.
Let’s look at the data, collection methods, and analysis methods in turn.
1.1 Data Types
Logs, metrics, and traces describe different aspects of a running system. They are not three file formats or an exhaustive classification of logs: profiles also describe resource usage at code level. A JSON file, database, or binary stream can carry several kinds of signal. The recording only tells us what its instrumentation and capture settings observed; it cannot reconstruct every part of the system. See the OpenTelemetry signal definitions.

The diagram uses a simplified Counter / State distinction, not the full instrument taxonomy of any telemetry standard.
Log Type
A log records an event, usually with a timestamp, source, severity, and message or structured fields. Text lines are common, but binary and structured logging also exist. Logs with suitable timestamps and identifiers can produce metrics or help reconstruct traces; missing correlation fields cannot be recovered by changing the storage format.
Error, warning, and debug levels help filter records, but severity is not a ranking of performance relevance. A scheduling delay may have no error log at all. Select records according to the question, and keep the cost of formatting, collection, and storage in mind.
Metric Type
Metrics record numerical measurements such as CPU utilization, CPU frequency, and context-switch counts. Distinguish a gauge or instantaneous observation from a cumulative counter and from a statistic aggregated over a window. A counter needs differences between observations, elapsed time, and reset handling before it can be interpreted as a rate.
For average CPU utilization over five minutes, state the time window and denominator: one core, all cores, or a process. Equally spaced utilization samples may be averaged arithmetically; unequal intervals require time weighting. Giving recent samples more weight produces a different statistic. Missing samples are unknown, not zero, and a mean can hide short spikes.
Typed numerical data often reduces parsing work and can save space, but metrics do not inherently use fixed-width storage, nor do logs necessarily use ASCII. Encoding, labels and their cardinality, compression, and sampling frequency determine the actual cost. An enum may describe a state, but averaging its numeric codes usually has no useful meaning.
Trace Type
Trace events can record names, timestamps, intervals, counters, and relationships. They help investigate function execution, Binder transactions, and work spanning threads or processes. Parent-child relationships or asynchronous flow identifiers must be recorded or derived from a defined protocol; nearby timestamps alone do not establish causality.
Android apps interact with system services through Binder. Following a transaction may require client, server, and scheduler data. A long synchronous call includes possible queueing and waiting as well as execution; it is not automatically time spent on the CPU.
Manually instrumented sections and method entry/exit tracing provide explicit boundaries for the code they cover. They do not reveal uninstrumented functions, and dense method tracing can substantially perturb execution. Nested durations also cannot simply be added without double-counting.
Stack sampling answers a different question: which stacks were observed, and how much sampled weight they account for. It does not record every invocation or exact entry/exit times, and short functions can be missed. A shorter interval may improve coverage but increases collection cost and does not guarantee a more accurate result. “Profiler” includes sampling and instrumentation tools, rather than naming sampling alone.
1.2 Data Acquisition Methods

Static Instrumentation and Dynamic Tracing
Static instrumentation adds recording points in source code, generated code, or libraries. Adding a missing point often requires a rebuild and deployment; existing switches may enable points already present. If one recording lacks a needed event, other signals or a new capture may still help.
Dynamic tracing can attach to existing tracepoints or add probes without editing the target source. It does not require every probe to have been embedded by the application, or require a dynamically typed language. For example, Linux uprobes can instrument userspace binary offsets when the kernel supports them; kprobes target kernel code.
Android includes eBPF infrastructure, but that does not grant an ordinary app unrestricted tracing access. Availability depends on kernel features, probe support, privileges, and SELinux policy. Choose the mechanism for the target build and deployment environment rather than assuming it is restricted to kernel developers or available on every retail phone.
Unconditional and Conditional Capture
Unconditional capture records the selected sources for a configured session without an anomaly trigger. Its cost depends on source frequency, stack collection, buffering, and storage. Reduce unnecessary data while retaining the events needed to answer the question.
Conditional capture uses a detector to start or finish a recording. The detector itself has a cost. Starting after an anomaly cannot recover events that were never recorded; continuously collecting into a bounded buffer and stopping after an anomaly can retain recent history, but collection still consumes resources before the trigger. These are different strategies, not a guarantee of zero overhead outside failures.
Dumping Strategy
Continuous file output supports longer recordings but adds I/O and storage costs. Alternatively, a ring buffer can retain recent data in memory until a trigger finalizes the capture. Its capacity and event rate limit how much history survives: old data is overwritten, and producer-side loss can occur independently.
Perfetto distinguishes overwrite and discard policies and can periodically drain buffers to a file. A trigger does not guarantee that the root cause remains in the buffer. Check capture duration, enabled sources, buffer sizing, and reported data loss before treating an absent event as evidence. See buffer behavior and trace configuration.
1.3 Analysis Methods

Data Visualization Analysis
A timeline places events on process, thread, or other tracks so that their timing and recorded relationships can be examined together. Systrace and Perfetto provide this view; KernelShark serves related Linux tracing workflows. Overlapping intervals are useful clues but do not by themselves prove that one caused another.
The historical Systrace viewer belongs to the Catapult project. Its Trace Event Format is a specific schema, not a promise that any JSON log will render as a trace. Modern Perfetto also imports supported formats; check the format list for the actual input.
Database Analysis
Turning captured data into tables makes repeatable queries and aggregation possible. Perfetto’s Trace Processor exposes trace data through SQL; Python can organize queries and results into an automated analysis. Search systems such as Elastic’s stack provide another way to explore structured logs, with their own query model.
Text inspection, visualization, and SQL complement each other. A quick text search may locate an event; a timeline may explain its context; SQL may compare many occurrences. None is mandatory merely because a problem involves several modules. Preserve units, time boundaries, and correlation identifiers when converting data so that the analysis still answers the original question.
2 Google-Provided Android Performance Analysis Tools
The three tools discussed here are Systrace, Perfetto, and Android Studio Profiler. These were common starting points in our workflow when this article was written. Choose tools according to the evidence needed: a heap problem, for example, may call for a memory tool first. The comparison below summarizes scope rather than prescribing a fixed sequence.
2.1 First-Generation System Performance Analysis Tool — Systrace
Systrace is a historical Android system-tracing workflow that visualizes selected app, framework, and kernel events. It was never the only performance tool. System tracing is often less intrusive than recording every method entry and exit, but its overhead is not zero and varies with enabled categories and event volume. For new investigations, start with Android system tracing and Perfetto.

Systrace’s Design Philosophy
Android instrumentation marks selected operations such as input dispatch, rendering, and inter-process communication. Userspace markers produced through android.os.Trace or native ATrace APIs are distinct from kernel events such as sched_switch and cpu_idle; the historical capture path can collect them together through ftrace.

The screenshot shows both tracing_mark_write markers and kernel events. Java framework code and application code can emit trace sections; native framework code has corresponding ATrace facilities. Categories, app selection, permissions, kernel support, and buffer loss determine what is actually captured. The result exposes useful parts of system activity, not every operation in Android.
Practical Application Scenarios
System traces help investigate startup, slow interactions, scrolling, window animations, and periods of apparent unresponsiveness. Scheduler and Binder events can distinguish execution from some forms of waiting when the relevant sources were captured.
An ANR investigation also needs its reason and thread stacks; a crash may require logcat, an exception stack, or a native tombstone. A timeline alone does not explain every failure. Old Systrace HTML files belong to the historical viewer workflow; for a new recording use the current system-tracing tools and open a supported trace in Perfetto UI.
2.2 New-Generation Performance Analysis Tool Stack — Perfetto
Perfetto provides recording, visualization, and analysis components for system and application tracing. It is the current Android system-tracing direction. Support for importing a format is also separate from having every historical viewer feature.
The service model separates producers, data sources, the tracing service, and consumers. This architecture supports sources beyond ftrace and allows several kinds of data to share a recording.
Highlighted Features
A producer supplies data for configured sources; the service manages sessions and buffers. Kernel ftrace events and Android userspace markers are important sources, but process statistics, heap profiling, and other sources have different collection paths. The native trace format uses protobuf messages; it is not a SQLite database.

Perfetto can capture into memory or stream to a file. Long recordings still depend on buffer capacity, source rate, storage, and overhead. The official Android log source is documented as userdebug-only: logcat is not guaranteed to be present in an ordinary user-build trace. Missing tracks or samples do not mean zero activity.
The UI, command-line tools, and Android’s System Tracing app provide different recording entry points. The trigger API activates names in a session configured in advance by an authorized consumer. START_TRACING begins recording after the trigger; STOP_TRACING can finalize an already recording session and retain bounded pre-trigger history. An app activating a trigger does not thereby gain permission to configure arbitrary system-wide tracing.
Trace Processor parses a trace and provides SQL tables through the UI, command line, and APIs. You do not have to export a SQLite file first. Python and DataFrames can help automate analysis. Large traces may benefit from a native Trace Processor, but memory and parsing limits remain; “300 MB” is not a universal failure threshold for either viewer.
For CPU totals, identify whether SurfaceFlinger means the process or one thread, then sum captured running intervals clipped to the chosen time window. Summing nested function wall times would double-count and include waiting. Likewise, map CPU IDs to the device’s actual topology before labeling a core as big or little.
Practical Application Scenarios
Perfetto is a useful first tool for many system timing questions. Its flexibility does not make it an arbitrary dynamic-probe framework like an eBPF-based tracing setup, and it cannot manufacture events that its sources did not record.
Do not infer a high or negligible runtime cost from protobuf encoding alone. Measure the selected sources, sampling, buffers, and file output under the intended workload. The command-line Trace Processor supports scripted SQL and text output as well as interactive investigation; analysis is not limited to the webpage.
2.3 Android Studio Profiler Tools
Android Studio integrates profiling with application development. Its current Profiler workflow is organized around tasks and recordings; the old “CPU, Memory, Network, Battery” list is not a reliable map of today’s UI.
Network Inspector is under View → Tool Windows → App Inspection, with support depending on the networking library. Power Profiler, introduced in Android Studio Hedgehog 2023.1.1, uses supported device data; ODPM power rails require supported Pixel hardware, rather than being a generic battery meter on every Android phone.
Use a release-like, profileable build where the chosen task supports it. Some tasks, including Java/Kotlin allocation recording and heap dumps, require a debuggable app. Record Studio, Android, app build, and capture settings when comparing results; changing debug mode or instrumentation changes the measurement conditions.
Highlighted Features
The historical CPU Profiler menu below offers several different kinds of evidence:
- System Trace records selected scheduling, rendering, and instrumented intervals. UI aggregation or filtering is not the same as a guarantee that all short events were discarded. Export a supported recording to Perfetto UI when broader system analysis is useful.
- Java/Kotlin sampling or method tracing: stack samples estimate where execution is observed; instrumented entry/exit records expose call boundaries with greater perturbation. They are not interchangeable measurements.
- Native sampling, backed by simpleperf in the historical workflow, identifies sampled native stacks. It is not a complete C/C++ entry/exit trace. Simpleperf supports hardware PMU events and software events; available events, stack unwinding, and symbols depend on the target. See the simpleperf documentation.

This is an old Studio menu, retained to explain the original example. Current task names and available recording options depend on the Studio and Android versions.
Practical Application Scenarios
Slow response and jank are common timing problems, alongside memory, power, and other performance concerns. For an unfamiliar rendering problem, a system trace can locate a long interval, then method or native profiling can provide more detail. Choose the next recording according to the unresolved question rather than always running all three tools.

Suppose you’re handed a badly performing app and don’t know its code. Where would you start? In this historical example, egl_core has a long onDrawFrame interval. The selected interval is about one second of elapsed time. Its name alone does not establish the underlying source method or the amount of CPU work; use source instrumentation and scheduler data to check those points.

The Java recording points toward Utils.onDraw. Its selected interval shows roughly 1 s wall time but only 402 μs CPU time, suggesting waiting in this recording rather than one second of computation. That distinction matters before deciding what to optimize.

The native view contains Java_com_gl_shader_Utils_onDraw → sleep → nanosleep. This makes sleeping a candidate explanation for the delay. The three screenshots come from separate recordings, and their displayed CPU-time fields cannot be combined into a single CPU accounting result. The original complete captures and example source are not available here. Confirm the sleep call in source, correlate scheduling in a new capture, and repeat the same scenario after removing it before claiming a verified fix.
Studio’s integration makes this drill-down convenient for application developers. System-wide analysis may still need additional tools and permissions.
2.4 Comprehensive Comparison
Capture triggers, buffering, and file output are separate choices. The following table describes capabilities, not a claim that every tool continuously writes every event to disk.
| Tool | Main use | Evidence and limits |
|---|---|---|
| Systrace | Historical Android system tracing | Selected kernel events and userspace markers; legacy viewer workflow |
| Perfetto | System and app tracing | Events, counters, stacks, and other configured sources; memory/file and trigger modes; UI and SQL analysis |
| Android Studio Profiler | App-focused profiling tasks | System traces, samples, method records, heap or allocation data depending on the task and build |
| simpleperf | CPU event counting and stack sampling | Hardware or software events; sampled weight is not invocation count; text and visual reports |
| Snapdragon Profiler | Supported Snapdragon platforms | CPU, GPU, and some DSP analysis; DSP support is not universal |
| Historical Mali Graphics Debugger / Graphics Analyzer | Graphics API debugging on supported devices | Arm says Graphics Analyzer was last included in Performance Studio 2024.2; consult current Arm tools for the applicable workflow |
| Android logcat / dumpsys | Event logs / service diagnostics | Log buffers and service-specific snapshots or reports are different data sources; collection and redirection determine persistence |
| Android GPU Inspector | Supported Android GPU system/frame profiling | Device, driver, Android version, and graphics API requirements apply |
| eBPF-based tools | Programmable tracing and aggregation | Events, statistics, and stacks depending on the program and attachment point; requires suitable privileges and kernel support |
| ftrace | Linux tracing infrastructure | Kernel events, function tracing, and supported dynamic probes; buffer and output policies are configurable |
Choose GPU tools by the actual GPU, driver, OS, and API support matrix. A SoC vendor name alone does not establish Mali/Adreno compatibility.
3 About “Techniques, Methods, and Tools”
At the tool level, Linux and Android tools keep gaining data sources and bringing more information into one place. Those changes have a pattern. Learn what a tool can show you and when it is useful; the point is to solve problems more efficiently, not to spend all your time learning the next tool.
The technique level depends on knowing the system you work on: how a frame is drawn, how the CPU schedules work, how I/O is submitted. That knowledge helps you choose a tool and interpret its output. After enough experience, you can sometimes spot a useful clue before digging through every detail. You start connecting what you see with problems you’ve encountered before.
At the level of judgment, ask what problem you actually need to solve. How far does the improvement need to go? What will it cost, and what will you get for that effort? Which path is worth taking? What needs to happen first, and what depends on it?
We’ll use these three perspectives in the articles that follow. We want you to leave with more than one technique to copy: when the tool or even the system changes, you should still be able to ask useful questions, choose the information you need, and judge where to spend your effort.
4 About “The Performance Knowledge Planet”
Historical note: The following is the community plan we described in this 2022 article. The community closed in 2026 and no longer accepts members; these are the ideas we had then, not current service offers.
We started The Performance to exchange ideas and write useful articles together. The three organizers worked on performance at major phone manufacturers. We wanted to bring together the basics, methods, tools, and the part we valued most: real cases.
Here is what we planned to cover. The labels between # marks were tags, so readers could jump to the topics they cared about.
#ThePerformance# — Early chapters of the book we were planning, Android Performance Optimization: A Systematic Course. There were already plenty of good articles and libraries, but we wanted a book that connected principles, tools, and practice for app and system developers. We had a draft outline and expected to spend about a year writing it, sharing finished chapters along the way.
Part 1: → Performance Engineering
Part 2: → Analyzing Android Interaction and Core Systems from a Performance Perspective
Part 3: → Analyzing Linux Kernel Core Subsystem Design and Implementation
Part 4: → Problem Scenario Analysis Approach
Part 5: → Analysis and Debugging Tools
Part 6: → Quality Guardianship — Performance Monitoring Methods and Tools
#PerformanceTools# — Tools we used and how to use them, including one-to-one video sessions for Systrace and Perfetto. A live demonstration can make things much clearer; some steps are hard to explain in a static article.
#CaseAnalysis# — Case studies and discussions, including cases shared by community members. Reading real cases helps when a similar problem lands on your desk. We also welcomed people’s own cases and solutions, with sensitive details masked.
#ClassicReinterpretation# — Revisiting useful libraries, approaches, and courses such as the Android developer masterclass: compare solutions, read them closely, and fill gaps in our understanding.
#KnowledgeShare# — Good articles, blogs, tools, and open-source work that had been used in real projects. We would find and share material worth spending time on.
#KnowledgeDeposition# — Highlights from WeChat discussions, questions people asked us, and answers left in blog comments.
#PerformanceInterview# — Android performance interview questions and answers. A practical need for quite a few of us, I’d say.
#ProgrammingLanguage# — Programming language usage technique sharing.
#EfficiencyImprovement# — Ways to work more effectively, from engineering processes to useful tools. Time spent sharpening your tools pays off when you get back to work.
#IndustryDynamics# — First-time interpretation reports of new performance-related technologies, including but not limited to the following content:
- Industry summits, academic summit new concept interpretation reports
- Papers, industry, books, video introductions
- Android large version performance-related content introduction
- Android new hardware performance-related content introduction
- Android performance-related open source project interpretations
#BigNameSharing# — Monthly invitations to industry experts for experience sharing, case analyses

The community has closed. The QR image above is retained as part of the original article; please do not use it to make a payment.
5 Appendix
Perfetto Project Address
- Official usage documentation: https://perfetto.dev/docs/
- Github code library: https://github.com/google/perfetto, where you can report bugs or feature requests, and of course can submit PR contributions to contribute your strength.
Android GPU Inspector
- Official usage documentation: https://developer.android.com/agi
Other Major Manufacturers’ Performance Analysis Tools
About Me && Blog
Below is a personal introduction and related links. I look forward to communicating with colleagues in the same field. When three walk together, there must be my teacher!
- Blogger Personal Introduction: Inside are personal WeChat and WeChat group links.
- Blog Content Navigation: A navigation of personal blog content.
- Personally Organized and Collected Excellent Blog Articles - Essential Skills and Tools for Android Performance Optimization: Everyone is welcome to self-recommend and recommend (private WeChat chat is fine).
- Android Performance Optimization Knowledge Planet: The paid community stopped operating in 2026 and no longer accepts new members; this link preserves its history.
“An individual can move faster, a group can go further.”
