Skip to content

Most visited

Recently visited

navigation

Simpleperf

Simpleperf is a versatile command-line tool included in the NDK package that lets you perform CPU profiling for Android application processes. This tool can help you to find hot spots (that is, parts of native code that take up the most execution time in your app) for apps written in Java, C/C++, and Kotlin. Events correlated to a hot spot likely point to performance issues, so you should inspect and fix the source of hot spots if you care about your app’s performance.

You can run Simpleperf from any host development platform that the NDK supports. You can get the Simpleperf tool from NDK r13b and higher (under the ndk-location/simpleperf/ directory) or as a prebuilt from AOSP.

Requirements

To use Simpleperf, you must follow these requirements:

Usage

For the latest usage notes, refer to the Simpleperf README.

Quickstart

This section contains basic instructions for profiling an Android app with Simpleperf.

1. Prepare the app for profiling

The app to profile must be debuggable. In the <application> element of your app manifest, make sure that the android:debuggable attribute is set to true. This is already set for you if you are creating a new module in Android Studio.

Depending on whether you are profiling an app with Java or C++ code, you may also need to take these additional steps:

If you want to use Simpleperf to profile an Android app built with Unity, follow these steps to include debuggable symbols.

2. Configure the app profiling session

Simpleperf provides a Python script (app_profiler.py) to simplify how you run a profiling session. To configure the behavior of the script, you can modify the properties in the app_profiler.config file which is located in the ndk-location/simpleperf/ directory on your development machine.

The key properties are listed in the following table.

Property Name Description Example
app_package_name Package name of the app to profile. app_package_name="com.example.simpleperf.simpleperfexamplewithnative"
apk_file_path Path of the debuggable APK on your development machine for the app to profile. apk_file_path = "../SimpleperfExampleWithNative/app/build/outputs/apk/app-profiling.apk"
android_studio_project_dir Path of the Android Studio project on your development machine. android_studio_project_dir = "../SimpleperfExampleWithNative/"
launch_activity Main activity for the app your want to profile. launch_activity = ".GameMainActivity"
recompile_app Compiles Dalvik bytecode into native binaries with debug information. If profiling Java-only code, set to True. Otherwise, set to False. recompile_app = False
record_options Profiling options you want to pass as arguments to the 'simpleperf record' command running on the device. record_options = "-g --duration 10"

If you want to record call graph information for the profiling session, see Recording considerations for how to configure your record options.

3. Run the app profiler

To start the profiling session from your development machine, run the app_profiler.py script from the command line. You can find the script in the ndk-location/simpleperf/ directory.

$ python app_profiler.py

The script performs these actions:

4. Generate a profiling report

You can see the profiling report in text mode or in an interactive graphical user interface.

Simpleperf tips and recipes

If you are just starting out with Simpleperf, here are some commands that you may find particularly useful. For more commands and options, see Simpleperf Command Reference.

Find which shared libraries take the longest to execute

You can run this command to see which .so files take up the largest percentage of execution time (based on the number of CPU cycles). This is a good first command to run when starting your performance analysis session.

$ simpleperf report --sort dso

Find which functions take the longest to execute

Once you have identified which shared library takes most of the execution time, you can run this command to see the percentage of time spent executing the functions of that .so file.

$ simpleperf report --dsos library.so --sort symbol

Find percentage of time spent in threads

Execution time in a .so file can be split across multiple threads. You can run this command to see the percentage of time spent in each thread.

$ simpleperf report --sort tid,comm

Find the percentage of time spent in object modules

After finding the threads where most of the execution time is spent, you can use this command to isolate the object modules taking the longest execution time on those threads.

$ simpleperf report --tids threadID --sort dso

See how function calls are related

A call graph provides a visual representation of a stack trace that Simpleperf records during the profiling session. Before you start recording call graph information, see Recording considerations.

You can use the report -g command to print a call graph to see what functions are called by other functions. This is useful to determine if a function is slow by itself, or if it's because one or more of the functions it calls are slow.

$ simpleperf report -g

You can also use the Python script report.py -g to start an interactive tool that displays functions. You can click on each function to see how much time is spent in it's children.

Recording considerations

Simpleperf supports two primary ways to record the call graph information during a profiling session, namely DWARF-based (record --call-graph dwarf or record -g) and stack frame pointer-based (record --call-graph fp).

In general, recording with --call-graph fp is much faster than with --call-graph dwarf. You should consider using the --call-graph fp option if you are profiling on devices built on the AArch-64 architecture (arm64-v8a), but not on devices built on the ARM architecture (armeabi and armeabi-v7a). This is because devices built on the ARM architecture typically do not have stack frame registers to support reliable stack unwinding with the --call-graph fp option.

Instead, if you are profiling on devices built on the ARM architecture, consider using the --call-graph dwarf option. Using the --call-graph dwarf option enables Simpleperf to unwind the stack using the libunwind library. In order to use the --call-graph dwarf option, you must provide debug information in your native libraries. For this reason, we recommend that you build your APK to contain non-stripped native libraries.

Profiling apps built with Unity

If you are profiling an app built with Unity, make sure to build the app to include debuggable symbols by following these steps:

  1. Open your Android project in the Unity Editor.
  2. In the Build Settings window for the Android platform, make sure the Development Build option is checked.
  3. Click on Player Settings and set the Stripping Level property to Disabled.

Reporting problems

To report issues or make feature requests, use the android-ndk/ndk issue tracker on GitHub.

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)