0Pricing
Android Academy · Lektion

Performance messen

Profiler, Traces und Benchmarks

Performance messen ist eine kostenlose Android Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Android Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Android Academy-Kurs umfasst insgesamt 4 Lektionen.

Vor der Optimierung messen

Die goldene Regel bei Performance-Arbeiten lautet: erst messen, niemals raten. Die menschliche Intuition darüber, was langsam ist, liegt fast immer falsch.

In dieser Lektion lernen Sie die Werkzeuge kennen, die Android Ihnen gibt, um Performance zu sehen: die Profiler, System-Traces und Microbenchmarks. Sobald Sie messen können, wird jede Optimierung zu einer datengestützten Entscheidung statt zu einer Vermutung.

  • Profiler zeigen CPU, Speicher und Energie in Echtzeit.
  • System-Traces zeigen genau, wofür die Zeit jedes Frames verwendet wird.
  • Benchmarks liefern reproduzierbare Werte, die Sie über verschiedene Builds hinweg vergleichen können.

Das 16-ms-Frame-Budget

Auf einem Bildschirm mit 60 Hz zeichnet das System alle 16,67 ms ein neues Frame. Wenn Ihre App ein Frame nicht innerhalb dieses Zeitfensters vorbereiten kann, wird es verworfen, und Nutzer nehmen Jank (Ruckeln) wahr. Auf Geräten mit 120 Hz schrumpft das Budget auf etwa 8 ms.

Bei der Performance-Arbeit geht es im Wesentlichen darum, innerhalb dieses Budgets zu bleiben. Der folgende Kommentar zeigt die Rechnung, die Sie im Kopf behalten sollten.

// Frame budget math
// 60 Hz  -> 1000ms / 60  = 16.67ms per frame
// 90 Hz  -> 1000ms / 90  = 11.11ms per frame
// 120 Hz -> 1000ms / 120 =  8.33ms per frame
//
// Exceed the budget on the UI thread = a dropped frame = visible jank.
fun frameBudgetMs(refreshHz: Int): Double = 1000.0 / refreshHz

fun main() {
    println("60Hz  -> %.2f ms".format(frameBudgetMs(60)))
    println("120Hz -> %.2f ms".format(frameBudgetMs(120)))
}

Android Studio Profiler

Der Android Studio Profiler (View > Tool Windows > Profiler) verbindet sich mit einer laufenden App und zeigt Live-Zeitachsen für CPU, Speicher, Energie und Netzwerk.

  • CPU: Zeichnen Sie Methoden- und System-Traces auf, um zeitkritische Codepfade zu finden.
  • Speicher: Beobachten Sie Speicherzuweisungen und erstellen Sie Heap-Dumps, um Leaks zu finden.
  • Energie: Erkennen Sie Wakelocks und übermäßige Jobs, die den Akku entladen.

Erstellen Sie Profile immer mit einem Release-ähnlichen Build auf einem echten Gerät. Debug-Builds und Emulatoren liefern irreführende Werte, weil Optimierungen deaktiviert sind.

Macrobenchmark für reale Szenarien

Die Bibliothek Jetpack Macrobenchmark misst vollständige Nutzerabläufe (Start, Scrollen, Navigation) auf einem echten Gerät und liefert stabile Messwerte wie Frame-Zeiten und Startzeit.

Sie schreiben einen Test, der Ihre App startet und einen Ablauf ausführt. Die Bibliothek führt ihn viele Male aus und liefert Median- sowie 99. Perzentil-Werte.

@RunWith(AndroidJUnit4::class)
class StartupBenchmark {
    @get:Rule val rule = MacrobenchmarkRule()

    @Test
    fun coldStartup() = rule.measureRepeated(
        packageName = "com.example.app",
        metrics = listOf(StartupTimingMetric()),
        iterations = 5,
        startupMode = StartupMode.COLD
    ) {
        pressHome()
        startActivityAndWait()
    }
}

Microbenchmark für zeitkritischen Code

Wenn Sie wissen müssen, wie schnell eine einzelne Funktion ist, verwenden Sie die Bibliothek Microbenchmark. Sie führt Ihren Code in einer engen Schleife aus, wärmt den JIT auf und gibt Nanosekunden pro Operation aus, bereinigt um Messrauschen.

Verwenden Sie sie für Parser, Serializer, Sortierungen oder Hilfsfunktionen mit CPU-Bindung, die Sie häufig aufrufen.

@RunWith(AndroidJUnit4::class)
class JsonParseBenchmark {
    @get:Rule val benchmarkRule = BenchmarkRule()

    @Test
    fun parseLargePayload() {
        val raw = loadSampleJson()
        benchmarkRule.measureRepeated {
            val parsed = parseUsers(raw) // code under test
            // assertEquals avoids the compiler dropping the result
            assertTrue(parsed.isNotEmpty())
        }
    }
}

System-Tracing mit Perfetto

System-Tracing zeichnet auf, was jeder Thread und das System Frame für Frame getan haben. Der CPU-Profiler von Android Studio kann einen solchen Trace aufzeichnen. Sie können ihn auch mit adb erfassen und in Perfetto (ui.perfetto.dev) öffnen.

Ein Trace zeigt die gefürchteten roten Frames, die Arbeit im Hauptthread und die Zeit, die in der GPU verbracht wird. Er ist das wichtigste Werkzeug zur Diagnose von Jank.

# Record a 5-second system trace from the command line
adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto-trace \
  -t 5s sched freq idle am wm gfx view

# Pull it to your machine, then open in https://ui.perfetto.dev
adb pull /data/misc/perfetto-traces/trace.perfetto-trace

Benutzerdefinierte Trace-Abschnitte

Standardmäßig zeigen Traces Framework-Arbeit. Um eigenen Code zu kennzeichnen, schließen Sie ihn in einen benannten Trace-Abschnitt ein. Diese Namen erscheinen dann als beschriftete Blöcke in Perfetto, sodass Sie Ihre Hotspots leicht erkennen.

Verwenden Sie die API androidx.tracing, damit die Abschnitte sowohl in Debug- als auch in Benchmark-Traces angezeigt werden.

import androidx.tracing.trace

fun loadDashboard(repo: Repo): Dashboard {
    return trace("loadDashboard") {
        val user = trace("fetchUser") { repo.user() }
        val feed = trace("fetchFeed") { repo.feed() }
        Dashboard(user, feed)
    }
}
// In Perfetto you will now see named slices:
// loadDashboard > fetchUser, fetchFeed

Verworfene Frames zur Laufzeit verfolgen

Sie haben nicht immer einen Profiler angeschlossen. JankStats ist eine Jetpack-Bibliothek, die ruckelnde Frames innerhalb Ihrer laufenden App meldet. So können Sie sie protokollieren oder aggregierte Daten an Ihre Analytics senden.

Die Bibliothek klinkt sich in das Fenster ein und ruft Sie jedes Mal zurück, wenn ein Frame sein Budget überschreitet.

val jankStats = JankStats.createAndTrack(window) { frameData ->
    if (frameData.isJank) {
        Log.w("Jank", "Janky frame: ${frameData.frameDurationUiNanos} ns")
        analytics.logJank(frameData.frameDurationUiNanos)
    }
}

// Pause/resume with your screen lifecycle
override fun onResume() { super.onResume(); jankStats.isTrackingEnabled = true }
override fun onPause() { super.onPause(); jankStats.isTrackingEnabled = false }

Die Zahlen lesen: Perzentile

Ein einzelner Durchschnittswert verbirgt problematische Ausreißer. Wenn Ihr durchschnittliches Frame 10 ms benötigt, das 99. Perzentil aber bei 40 ms liegt, sind 1 % der Frames ruckelig, und Nutzer spüren das. Betrachten Sie immer P50, P90, P99, nicht nur den Mittelwert.

Benchmarks liefern diese Werte automatisch. Der folgende Helfer veranschaulicht das Prinzip anhand roher Frame-Messwerte.

fun percentile(samplesMs: List<Double>, p: Int): Double {
    val sorted = samplesMs.sorted()
    val index = ((p / 100.0) * (sorted.size - 1)).toInt()
    return sorted[index]
}

fun main() {
    val frames = listOf(8.0, 9.0, 10.0, 9.5, 11.0, 40.0, 9.0, 10.5)
    println("P50 = %.1f ms".format(percentile(frames, 50)))
    println("P99 = %.1f ms".format(percentile(frames, 99)))
}

Ein reproduzierbarer Messablauf

Verlässliche Messwerte entstehen durch einen disziplinierten Prozess. Befolgen Sie jedes Mal diese Checkliste:

  • Verwenden Sie einen Release-/nicht debuggbaren Build (R8 aktiviert).
  • Führen Sie den Test auf einem physischen Gerät durch, das am Stromnetz hängt und einen stabilen thermischen Zustand hat.
  • Wiederholen Sie das Szenario mehrere Male und geben Sie den Median an.
  • Ändern Sie jeweils nur eine Sache und messen Sie erneut.
  • Vergleichen Sie mit einer gespeicherten Baseline, damit Sie eine Verbesserung nachweisen können.

Wenn Sie diese Punkte überspringen, jagen Sie Messrauschen hinterher, statt echte Probleme zu beheben.

Wohin die Zeit tatsächlich fließt

Die meisten Jank-Probleme unter Android entstehen durch eine kleine Gruppe von Ursachen. Wenn Sie diese kennen, wissen Sie, worauf Sie Ihre Werkzeuge ansetzen müssen:

  • Arbeit im Hauptthread: Datenträgerzugriffe, Netzwerk und JSON im UI-Thread.
  • Übermäßige Recompositions: Compose zeichnet viel zu große Teile der UI erneut.
  • Zu viele Speicherzuweisungen: Pausen durch die Garbage Collection.
  • Layout-Pässe: tief verschachtelte oder wiederholt gemessene Layouts.

Die nächsten Lektionen dieses Kurses behandeln Recompositions, Memory-Leaks und den Startvorgang direkt. Messungen zeigen Ihnen, welches Problem Sie zuerst beheben sollten.

Kurztest

Sie möchten auf einem echten Gerät über mehrere Durchläufe hinweg stabil und reproduzierbar messen, wie lange der kalte Start Ihrer App dauert. Welches Werkzeug eignet sich am besten?

Zusammenfassung: Sie können jetzt messen

Sie haben gelernt, Performance sichtbar zu machen, bevor Sie etwas ändern:

  • Das 16-ms-Frame-Budget legt fest, ob die Darstellung flüssig oder ruckelig ist.
  • Der Android Studio Profiler zeigt CPU, Speicher und Energie live an.
  • Macro- und Microbenchmarks liefern reproduzierbare Messwerte.
  • Perfetto-Traces und benutzerdefinierte trace()-Abschnitte zeigen, wohin die Zeit fließt.
  • JankStats meldet Jank aus der laufenden App heraus.
  • Lesen Sie P50/P90/P99, erstellen Sie Profile von Release-Builds auf echten Geräten und ändern Sie jeweils nur eine Sache.

Als Nächstes wenden wir das auf eine der größten Ursachen für Compose-Jank an: Recompositions.

Häufig gestellte Fragen

Ist die Lektion „Performance messen“ kostenlos?

Ja — der vollständige Text von „Performance messen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Android Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Android Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Performance messen“?

Profiler, Traces und Benchmarks Du übst Android Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Android Academy zu starten?

Keine Vorkenntnisse erforderlich. Android Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.

Wie lange dauert die Lektion „Performance messen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Android Academy-Lektion Code schreiben und ausführen?

Ja. Jede Android Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Performance messen
  2. Recomposition bändigen
  3. Memory Leaks und ihre Behebung
  4. Startup- und Baseline-Profile
← Zurück zu Android Academy