If you do prefer to use the command line, 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 on Linux, Mac, or Windows. The simpleperf tool is in the NDK under the ndk-location/simpleperf/ directory, or you can download early-access prebuilts from AOSP.


To use Simpleperf, you must follow these requirements:

  • Use a device running Android 5.0 (API level 21) or higher to profile your app.
  • Connect the device to your development machine with a USB debugging connection.
  • To run the Python scripts for recording and reporting (recommended), install the following on your development machine:

    • Python 2.7 or higher.
    • The latest version of the Android SDK and NDK. You can install these via the SDK Manager in Android Studio.


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


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 are profiling Java code and are using a device running Android O, you must add the file to your APK. See the sample Gradle build script for Java code on how to package into your APK.
  • If you are profiling an app that contains C++ code or pre-compiled native libraries:

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 ( 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 script from the command line. You can find the script in the ndk-location/simpleperf/ directory.

$ python

The script performs these actions:

  • Pushes a copy of the Simpleperf executable to the Android device, based on the device architecture (for example, if the target device is based on ARM64, the script copies the ndk-location/simpleperf/bin/android/arm64/simpleperf executable to the device).
  • Runs the 'simpleperf record' command on the device. If successful, this command generates a file with the collected profile information.
  • Sends a copy of the generated file back to the development machine. By default, the file is saved to the ndk-location/simpleperf/ directory. To change the output location, modify the perf_data_path property in your app_profiler.config file.

4. Generate a profiling report

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

  • Text mode: Run the 'simpleperf report' command using the Simpleperf executable for your host platform. For example, if your development machine is running Linux, run the report command using ndk-location/simpleperf/bin/linux/x86_64/simpleperf.
  • Graphical mode: Run the script from the command line. The script is located in the ndk-location/simpleperf/ directory. The script also accepts the same arguments as the 'simpleperf report' command.

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 --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 -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.

See also

  1. Simpleperf Command Reference