Profiling a Microbenchmark

By default, Microbenchmarks give you information about the timing and allocations of the executed code. If you want to investigate why the measured code is running slowly, you can run the benchmarks with the CPU profiler attached. You can select the profiler configuration by adding an instrumentation runner argument androidx.benchmark.profiling.mode with one of MethodTracing, StackSampling, or None argument (as shown in the following snippet). To get more information about the options, see Choose a recording configuration.

Groovy

android {
    defaultConfig {
        // must be one of: 'None', 'StackSampling', or 'MethodTracing'
        testInstrumentationRunnerArguments["androidx.benchmark.profiling.mode"]= 'StackSampling'
    }
}

Kotlin

android {
    defaultConfig {
        // must be one of: 'None', 'StackSampling', or 'MethodTracing'
        testInstrumentationRunnerArguments["androidx.benchmark.profiling.mode"] = "StackSampling"
    }
}

When you profile a benchmark, an output .trace file will be copied to host, in the directory alongside JSON results. Open this file with Android Studio using File > Open to inspect profiling results in the CPU Profiler.

MethodTracing

With method tracing, the benchmark warms up before capturing a method trace, recording every method called by your benchmark. Performance results are significantly affected by the overhead of capturing each method entry/exit.

StackSampling

With stack sampling, the benchmark samples call stacks after the warmup has completed. You can control the sample frequency and duration of sampling using instrumentation arguments.

On Android 10 (API 29) and higher, stack sampling uses Simpleperf to sample app callstacks, including C++ code. On Android 9 (API 28) and lower, it uses Debug.startMethodTracingSampling to capture stack samples.

You can configure this profiling mode by adding another instrumentation arguments:

  • androidx.benchmark.profiling.sampleFrequency

    • Number of stack samples to capture per second
    • Argument type: integer
    • Defaults to 1000 samples per second.
  • androidx.benchmark.profiling.sampleDurationSeconds

    • Duration of benchmark to run.
    • Argument type: integer
    • Defaults to 5 seconds.

None

Doesn’t capture a profiling file. Information about timing and allocations are still measured.