Skip to content

Latest commit

 

History

History
153 lines (128 loc) · 5.14 KB

File metadata and controls

153 lines (128 loc) · 5.14 KB

MACRObenchmarking in AndroidX

[TOC]

Macrobenchmark Benchmark
Measure high-level entry points (Activity launch / Scrolling a list) Measure individual functions
Out-of-process test of full app In-process test of CPU work
Slow iteration speed (Often more than a minute) Fast iteration speed (Often less than 10 seconds)
Configure compilation with CompilationMode Always fully AOT (speed) compiled.
Min API 23 Min API 19
Relatively lower stability measurements Higher stability measurements

The public documentation for macrobenchmark explains how to use the library. This page focuses on specifics to writing library macrobenchmarks in the AndroidX repo. If you're looking for measuring CPU perf of individual functions, see the guide for MICRObenchmarks here.

Writing the benchmark

Benchmarks are just regular instrumentation tests! Just use the MacrobenchmarkRule provided by the library:

Kotlin {.new-tab}

    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun startup() = benchmarkRule.measureRepeated(
        packageName = "mypackage.myapp",
        metrics = listOf(StartupTimingMetric()),
        startupMode = StartupMode.COLD,
        iterations = 10
    ) { // this = MacrobenchmarkScope
        pressHome()
        val intent = Intent()
        intent.setPackage("mypackage.myapp")
        intent.setAction("mypackage.myapp.myaction")
        startActivityAndWait(intent)
    }

Java {.new-tab}

    @Rule
    public MacrobenchmarkRule mBenchmarkRule = MacrobenchmarkRule()

    @Test
    public void startup() {
        mBenchmarkRule.measureRepeated(
                "mypackage.myapp",
                Collections.singletonList(new StartupTimingMetric()),
                StartupMode.COLD,
                /* iterations = */ 10,
                scope -> {
                    scope.pressHome();
                    Intent intent = Intent();
                    intent.setPackage("mypackage.myapp");
                    intent.setAction("mypackage.myapp.myaction");
                    scope.startActivityAndWait(intent);
                    return Unit.INSTANCE;
                }
        );
    }

Project structure

As in the public documentation, macrobenchmarks in the AndroidX repo are comprised of an app, and a separate macrobenchmark test module. In the AndroidX repository, there are additional requirements:

  1. Macrobenchmark test module path in settings.gradle must end with macrobenchmark to run in CI.

  2. Macrobenchmark target module path in settings.gradle must end with macrobenchmark-target to follow convention.

  3. Each library group should declare its own in-group macrobenchmark test and app module. More than one is allowed, which is sometimes necessary to compare different startup behaviors, see e.g. :emoji2:integration-tests:init-<disabled/enabled>-macrobenchmark-target. Note that comparing multiple app variants are not currently supported by CI.

Compose Macrobenchmark Examples:

Note: Compose macrobenchmarks are ideally duplicated with View system counterparts, defined in :benchmark:integration-tests:macrobenchmark-target. This is how we compare performance of the two systems.

Setup checklist

Did you setup... Required setup
Two modules in settings.gradle Both the macrobenchmark and target must be added for your group
The module name for the benchmark (com.android.test) module Must end with macrobenchmark
The module name for the app (com.android.app) module Must end with macrobenchmark-target
Name the test class in a discoverable way Test classes should have standalone names for easy discovery in the web UI. E.g EmojiStartupTest instead of StartupTest.