Android Academy · Lektion

Mäta prestanda

Profilerare, spårningar och prestandatester.

Lektion 1 av 413 steg

Mäta prestanda är en gratis lektion i Android Academy på CoddyKit. Detta är lektion 1 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Android Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Android Academy innehåller totalt 4 lektioner.

Mät innan ni optimerar

Den gyllene regeln för prestandaarbete är: mät först, gissa aldrig. Människans intuition om vad som är långsamt är nästan alltid fel.

I den här lektionen lär ni er vilka verktyg Android erbjuder för att se prestandan: profilerare, systemspårningar och mikroriktmärken. När ni kan mäta blir varje optimering ett databaserat beslut i stället för en gissning.

  • Profilerare visar CPU, minne och energiförbrukning i realtid.
  • Systemspårningar visar exakt vart tiden för varje bildruta tar vägen.
  • Riktmärken ger jämförbara siffror som ni kan jämföra mellan byggen.

16 ms bildbudget

På en skärm med 60 Hz ritar systemet en ny bildruta var 16,67 ms. Om appen inte hinner förbereda en bildruta inom det tidsfönstret tappas bildrutan, och användaren upplever jank (hackningar). På enheter med 120 Hz krymper budgeten till ungefär 8 ms.

Prestandaarbete handlar i praktiken om att hålla sig inom den här budgeten. Kommentaren nedan visar den matematik som man hela tiden har i åtanke.

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

Android Studio Profiler (View > Tool Windows > Profiler) ansluter till en app som körs och visar tidslinjer i realtid för CPU, minne, energi och nätverk.

  • CPU: spela in metodspårningar och systemspårningar för att hitta kodvägar med hög belastning.
  • Memory: övervaka allokeringar och samla in heap-dumpar för att hitta läckor.
  • Energy: upptäck wakelocks och överflödiga jobb som tömmer batteriet.

Profilera alltid en release-liknande build på en riktig enhet. Debug-byggen och emulatorer ger missvisande värden eftersom optimeringar är avstängda.

Macrobenchmark för verkliga scenarier

Biblioteket Jetpack Macrobenchmark mäter hela användarflöden (uppstart, rullning och navigering) på en riktig enhet och rapporterar stabila mätvärden som bildrutetider och uppstartstid.

Ni skriver ett test som startar appen och genomför ett flöde. Biblioteket kör det många gånger och ger er medianvärden samt värden för 99:e percentilen.

@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 kod med hög belastning

När ni behöver veta hur snabbt en enskild funktion körs använder ni biblioteket Microbenchmark. Det kör koden i en tät loop, värmer upp JIT och rapporterar nanosekunder per operation, med bruset bortfiltrerat.

Använd det för parsers, serialisering, sortering eller andra CPU-bundna hjälpfunktioner som anropas ofta.

@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())
        }
    }
}

Systemspårning med Perfetto

Systemspårning fångar vad varje tråd och systemet gjorde, bildruta för bildruta. Android Studios CPU-profiler kan spela in en sådan spårning, och ni kan även fånga den med adb och öppna den i Perfetto (ui.perfetto.dev).

En spårning visar de fruktade röda bildrutorna, arbetet på huvudtråden och tiden som tillbringas i GPU:n. Det är det bästa enskilda verktyget för att diagnostisera 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

Egna spårningssektioner

Som standard visar spårningar arbete som utförs av ramverket. Om ni vill märka upp er egen kod omsluter ni den i en namngiven spårningssektion. Namnen visas sedan som märkta block i Perfetto, vilket gör det enkelt att upptäcka era flaskhalsar.

Använd API:et androidx.tracing så att sektionerna visas i både debug- och benchmarkspårningar.

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

Spåra tappade bildrutor under körning

Ni har inte alltid en profiler ansluten. JankStats är ett Jetpack-bibliotek som rapporterar hackiga bildrutor inifrån appen medan den körs, så att ni kan logga dem eller skicka sammanställningar till analysverktyg.

Det kopplar in sig i fönstret och anropar er när en bildruta överskrider sin budget.

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 }

Tolknings av siffrorna: percentiler

Ett enda medelvärde döljer problemen. Om den genomsnittliga bildrutan tar 10 ms men 99:e percentilen är 40 ms, är 1 % av bildrutorna hackiga och användarna märker det. Titta alltid på P50, P90, P99, inte bara på medelvärdet.

Benchmarkverktyg rapporterar dessa åt er. Hjälpfunktionen nedan visar principen med råa bildruteprover.

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)))
}

Ett repeterbart mätarbetsflöde

Tillförlitliga värden kräver en disciplinerad process. Följ den här checklistan varje gång:

  • Använd en release-/icke-debuggbar build (R8 aktiverat).
  • Kör på en fysisk enhet som är ansluten till ström och har ett stabilt termiskt tillstånd.
  • Upprepa scenariot flera gånger och rapportera medianen.
  • Ändra en sak i taget och mät igen.
  • Jämför med en sparad baslinje så att ni kan bevisa förbättringen.

Om ni hoppar över detta jagar ni brus i stället för att åtgärda verkliga problem.

Vart tiden faktiskt tar vägen

Det mesta av jank i Android kommer från ett litet antal orsaker. Om ni känner till dem vet ni vart verktygen ska riktas:

  • Arbete på huvudtråden: disk, nätverk eller JSON på UI-tråden.
  • För mycket omkomposition: Compose ritar om alldeles för mycket.
  • Allokeringscirkulation: pauser för skräpsamling.
  • Layoutpass: djupt nästlade eller upprepade layoutmätningar.

Nästa lektioner i kursen behandlar omkomposition, minnesläckor och uppstart direkt. Det är mätningen som visar vilket problem ni bör åtgärda först.

Snabbkontroll

Ni vill ha en stabil och repeterbar mätning av hur lång tid appens kallstart tar på en riktig enhet över flera körningar. Vilket verktyg passar bäst?

Sammanfattning: Nu kan ni mäta

Ni har lärt er att göra prestanda synlig innan ni ändrar något:

  • En 16 ms bildbudget avgör om upplevelsen är jämn eller hackig.
  • Android Studio Profiler visar CPU, minne och energi i realtid.
  • Macro- och Microbenchmarks ger repeterbara värden.
  • Perfetto-spårningar och egna trace()-sektioner visar vart tiden tar vägen.
  • JankStats rapporterar jank inifrån appen medan den körs.
  • Läs av P50/P90/P99, profilera release-byggen på riktiga enheter och ändra en sak i taget.

Nästa steg är att tillämpa detta på en av de största orsakerna till jank i Compose: omkomposition.

Gratis att börja

Lär dig Kotlin med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
36
Lektioner
152

Vanliga frågor

Är lektionen ”Mäta prestanda” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Android Academy, inklusive ”Mäta prestanda”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Android Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Mäta prestanda”?

Profilerare, spårningar och prestandatester. Ni övar på Android Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Android Academy?

Du behöver inga förkunskaper. Utbildningen i Android Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.

Hur lång tid tar lektionen ”Mäta prestanda”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Android Academy-lektionen?

Ja. Varje Android Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Mäta prestanda
  2. Tämja rekompositionering
  3. Minnesläckor och åtgärder
  4. Start och baslinjeprofiler
← Tillbaka till Android Academy