Android Coden
Android 7 min lesen

Macrobenchmark

Macrobenchmarks messen Startzeit und Scroll-Performance auf echten Geräten. Du prüfst damit, ob deine App im Alltag schnell wirkt.

Macrobenchmark ist ein Werkzeug aus der Android-Welt, mit dem du messbare Antworten auf typische Performance-Fragen bekommst: Wie schnell startet deine App? Bleibt eine Liste beim Scrollen flüssig? Verhält sich ein realer Release-naher Build besser oder schlechter als vorher? Damit verschiebst du Performance weg vom Bauchgefühl und hin zu überprüfbaren Daten.

Was ist das?

Ein Macrobenchmark misst größere, sichtbare Abläufe deiner App von außen. Das unterscheidet ihn von einem kleinen Mikrobenchmark, der zum Beispiel nur eine einzelne Funktion oder Berechnung bewertet. Bei Macrobenchmark geht es um komplette Szenarien: App öffnen, erste Oberfläche anzeigen, durch eine Compose-Liste scrollen, zu einem Screen navigieren oder eine wiederkehrende Nutzeraktion ausführen.

Das mentale Modell ist wichtig: Du testest nicht nur Kotlin-Code, sondern das Zusammenspiel aus App-Prozess, Android-System, UI-Rendering, Datenzugriff, Layout, Compose-Recomposition, Ressourcen und Gerätezustand. Genau deshalb passt Macrobenchmark in moderne Android-Entwicklung. Eine App kann architektonisch sauber aussehen und trotzdem langsam starten, weil zu viel Arbeit beim Start passiert. Eine Compose-Liste kann fachlich korrekt sein und trotzdem ruckeln, weil Items instabil sind, Bilder ungünstig geladen werden oder unnötige Zustandsänderungen viele Recompositionen auslösen.

Im Roadmap-Kontext gehört Macrobenchmark in den Bereich Performance und Qualität. Du misst end-to-end auf realistischen Builds, also näher an dem, was Nutzer später wirklich erleben. Das ist auch ein Unterschied zu vielen lokalen Tests im Debug-Modus. Debug-Builds enthalten zusätzliche Prüfungen, sind oft nicht optimiert und liefern deshalb schlechte Vergleichswerte. Für aussagekräftige Messungen brauchst du Release-nahe Varianten, echte Geräte und wiederholbare Abläufe.

Warum ist das relevant? Performance ist Teil der User Experience. Ein langsamer Start kann dazu führen, dass Nutzer die App als träge empfinden, auch wenn die Funktionen korrekt sind. Ruckelndes Scrolling macht Inhalte schwerer erfassbar. Bei Accessibility spielt flüssige und vorhersagbare UI ebenfalls eine Rolle, weil Nutzer mit Screenreader, Vergrößerung oder motorischen Einschränkungen besonders auf stabile Interaktion angewiesen sind. Macrobenchmark ersetzt keine Accessibility-Tests, aber es hilft dir, Performance-Probleme sichtbar zu machen, die echte Bedienung stören können.

Wie funktioniert es?

Macrobenchmark wird typischerweise in einem separaten Testmodul eingerichtet. Dieses Modul startet deine App wie ein externer Nutzer und steuert sie über Instrumentation. Statt interne Methoden aufzurufen, interagiert der Test mit dem Paket deiner App. Dadurch misst du nicht isoliert eine Klasse, sondern das Verhalten des installierten Builds auf dem Gerät.

Ein zentraler Baustein ist MacrobenchmarkRule. Du definierst, welches Paket getestet wird, welche Metriken du erfassen willst und welche Aktion gemessen werden soll. Für den App-Start nutzt du zum Beispiel StartupTimingMetric. Für Scrollen und sichtbare Frame-Performance kommen Metriken wie FrameTimingMetric infrage. Dazu legst du fest, ob der Prozess vor jeder Messung neu gestartet wird und wie die App vor der Messung vorbereitet werden soll.

Bei Startup-Messungen ist besonders wichtig, was du eigentlich messen willst. Ein Cold Start bedeutet: Der App-Prozess ist nicht vorhanden, und Android muss Prozess, Application, Activity und erste UI vollständig aufbauen. Ein Warm Start ist näher an einem Rücksprung in eine bereits geladene App. Beide Werte können wichtig sein, aber sie beantworten verschiedene Fragen. Für viele Release-Checks ist der Cold Start ein guter erster Indikator, weil er sichtbar macht, wie viel Arbeit du beim Start bündelst.

Bei Scrolling-Messungen steuerst du eine konkrete Liste oder einen konkreten Screen. In Compose kann das zum Beispiel eine LazyColumn sein. Der Benchmark wischt wiederholt über die Oberfläche und sammelt Frame-Daten. Daraus erkennst du, ob viele Frames länger brauchen als geplant. Das ist praxisnäher als nur zu fragen, ob die Liste funktional angezeigt wird.

Ein weiterer Punkt ist die Wiederholbarkeit. Benchmarks sind empfindlich gegenüber Hintergrundprozessen, Akkuzustand, thermischer Drosselung, Animationen, Netzwerk und Datenmenge. Deshalb solltest du deine Testdaten kontrollieren, externe Netzwerkeffekte vermeiden und klare Startzustände schaffen. Wenn ein Benchmark mal schnell und mal langsam ist, ohne dass sich der Code geändert hat, misst du vermutlich zu viel Umgebung und zu wenig App-Verhalten.

Macrobenchmark gehört in die tägliche Entwicklung vor allem an drei Stellen. Erstens bei Performance-Arbeit: Du misst vor und nach einer Änderung. Zweitens bei Regressionen: Du erkennst, wenn eine neue Abhängigkeit, ein neuer Screen oder ein geänderter Startablauf den App-Start verschlechtert. Drittens in der Release-Praxis: Du prüfst auf einem echten Gerät, ob die App noch innerhalb eurer Zielwerte bleibt.

In der Praxis

Angenommen, du hast eine App mit einem Compose-Home-Screen. Der Screen lädt eine Liste von Artikeln und zeigt sie in einer LazyColumn. Du willst zwei Dinge prüfen: Startet die App schnell genug bis zur ersten Anzeige, und bleibt das Scrollen über die Liste stabil?

Ein vereinfachter Startup-Benchmark kann so aussehen:

@RunWith(AndroidJUnit4::class)
class StartupBenchmark {

    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun coldStartup() = benchmarkRule.measureRepeated(
        packageName = "de.android_coden.demo",
        metrics = listOf(StartupTimingMetric()),
        iterations = 10,
        startupMode = StartupMode.COLD,
        setupBlock = {
            pressHome()
        }
    ) {
        startActivityAndWait()
    }
}

Dieser Test startet die App mehrfach im Cold-Start-Modus und misst die Startzeit. Wichtig ist dabei nicht nur der einzelne Wert, sondern der Vergleich über Zeit. Wenn dein Start nach einer Änderung deutlich langsamer wird, hast du einen Hinweis. Dann prüfst du, ob du beim Start zu viel machst: große Datenbankabfragen, Initialisierung schwerer SDKs, blockierende I/O-Arbeit oder unnötige Navigation, bevor die erste UI sichtbar ist.

Für Scrolling sieht die Idee ähnlich aus, nur misst du Frames während einer UI-Aktion:

@RunWith(AndroidJUnit4::class)
class FeedScrollBenchmark {

    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun scrollFeed() = benchmarkRule.measureRepeated(
        packageName = "de.android_coden.demo",
        metrics = listOf(FrameTimingMetric()),
        iterations = 10,
        startupMode = StartupMode.WARM,
        setupBlock = {
            startActivityAndWait()
            device.wait(Until.hasObject(By.res("feed_list")), 5_000)
        }
    ) {
        val list = device.findObject(By.res("feed_list"))
        repeat(5) {
            list.fling(Direction.DOWN)
            device.waitForIdle()
        }
    }
}

Damit dieser Test funktioniert, braucht deine UI stabile Selektoren. In klassischen Views können das Resource-IDs sein. In Compose arbeitest du häufig mit Test-Tags, die über Semantics in die UI-Test-Welt sichtbar gemacht werden. Achte darauf, dass du nicht nur irgendein Element findest, sondern genau den Bereich steuerst, den du messen willst.

Eine praktische Entscheidungsregel: Miss zuerst einen kurzen, wichtigen Ablauf, der für Nutzer häufig vorkommt. Für viele Apps sind das Cold Startup und Scrollen im Hauptfeed oder in der wichtigsten Ergebnisliste. Ein Benchmark, der genau diese zwei Wege stabil prüft, ist wertvoller als zehn breite Tests, die selten laufen und ständig flackern.

Eine typische Stolperfalle ist der Debug-Build. Wenn du Macrobenchmarks gegen eine Debug-Variante laufen lässt, erhältst du Werte, die für Performance-Entscheidungen kaum taugen. Debug-Code, fehlende Optimierungen und zusätzliche Checks können Start und Rendering stark beeinflussen. Nutze eine passende Benchmark- oder Release-nahe Build-Variante. Prüfe außerdem, ob Minification, Baseline Profiles und Ressourcenverarbeitung so konfiguriert sind, dass der Build deiner echten Auslieferung ähnelt.

Eine zweite Stolperfalle ist Netzwerk im Benchmark. Wenn dein Startup-Test jedes Mal auf eine echte API wartet, misst du Server, WLAN, DNS und Gerätezustand mit. Für Performance-Vergleiche ist das meist nicht sinnvoll. Nutze vorbereitete Daten, Fakes, lokale Testdaten oder einen klar definierten Zustand. Du willst wissen, ob deine App schneller oder langsamer rendert, nicht ob das Netzwerk gerade freundlich ist.

Eine dritte Stolperfalle liegt im Umgang mit Ergebnissen. Ein einzelner Lauf beweist wenig. Betrachte mehrere Iterationen, vergleiche Median oder stabile Kennzahlen und achte auf Ausreißer. Wenn ein Wert stark streut, verbessere zuerst den Testaufbau. Erst wenn die Messung stabil ist, solltest du Code-Entscheidungen daraus ableiten.

In Code-Reviews kannst du Macrobenchmark-Fragen sehr konkret stellen: Wird beim Start neue Arbeit auf dem Main Thread erledigt? Lädt ein neuer Screen direkt große Bilder oder Datenmengen? Hat eine LazyColumn stabile Keys? Werden Compose-States so geschnitten, dass nicht die ganze Liste unnötig neu gezeichnet wird? Gibt es eine Messung für den kritischen Pfad, den die Änderung betrifft? Solche Fragen machen Performance zu einem normalen Qualitätskriterium, nicht zu einer späten Rettungsaktion vor dem Release.

Fazit

Macrobenchmark hilft dir, reale Performance-Szenarien deiner Android-App messbar zu machen: Startzeit, Scrollen und andere sichtbare Abläufe werden auf einem echten Gerät mit einem realistischen Build geprüft. Übe das an einem kleinen Projekt, indem du zuerst einen Cold-Startup-Benchmark einrichtest und danach eine wichtige Liste scrollen lässt. Vergleiche die Werte vor und nach einer bewussten Änderung, zum Beispiel einer zusätzlichen Initialisierung im Startpfad. Danach prüfst du im Debugger, mit Logs oder im Profiler, warum sich die Messung verändert hat. So lernst du, Performance nicht nur zu vermuten, sondern begründet zu bewerten.

Quellen (4)
Redaktion

Geschrieben von

Redaktion

Das Redaktionsteam recherchiert und schreibt Artikel zu aktuellen Themen rund um Tech, Lifestyle und Ratgeber.