Android Academy · Lektion

Måling af ydeevne

Profilere, traces og benchmarks.

Lektion 1 af 413 trin

Måling af ydeevne er en gratis Android Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Android Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Android Academy-kurset indeholder 4 lektioner i alt.

Mål, før du optimerer

Den gyldne regel for performancearbejde er: mål først, gæt aldrig. Menneskets intuition om, hvad der er langsomt, er næsten altid forkert.

I denne lektion lærer du de værktøjer, Android giver dig til at se performance: profilerne, systemsporene og mikrobenchmarks. Når du kan måle, bliver enhver optimering en datadrevet beslutning i stedet for en mavefornemmelse.

  • Profiler viser CPU, hukommelse og energiforbrug i realtid.
  • Systemspor afslører præcis, hvor hver frames tid bruges.
  • Benchmarks giver gentagelige tal, som du kan sammenligne på tværs af builds.

16 ms-framebudgettet

På en skærm med 60 Hz tegner systemet et nyt billede hver 16,67 ms. Hvis din app ikke kan forberede et billede inden for dette tidsrum, går billedet tabt, og brugerne oplever hak (stammen). På enheder med 120 Hz bliver budgettet reduceret til cirka 8 ms.

Performancearbejde handler i praksis om at holde sig inden for dette budget. Kommentaren nedenfor viser den matematik, du har i baghovedet.

// 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) kobler sig til en app, der kører, og viser tidslinjer i realtid for CPU, hukommelse, energi og netværk.

  • CPU: Optag metodespor og systemspor for at finde de mest belastede kodestier.
  • Memory: Hold øje med allokeringer, og tag heap-dumps for at finde lækager.
  • Energy: Find wakelocks og for mange job, der dræner batteriet.

Profiler altid et release-lignende build på en rigtig enhed. Debug-builds og emulatorer giver misvisende tal, fordi optimeringer er deaktiveret.

Makrobenchmarking af virkelige scenarier

Biblioteket Jetpack Macrobenchmark måler hele brugerforløb (opstart, rulning, navigation) på en rigtig enhed og rapporterer stabile målinger som billedtiming og opstartstid.

Du skriver en test, der starter din app og gennemfører et forløb; biblioteket kører den mange gange og giver dig medianen samt værdier ved 99-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()
    }
}

Mikrobenchmarking af belastet kode

Når du har brug for at vide, hvor hurtigt en enkelt funktion er, skal du bruge biblioteket Microbenchmark. Det kører din kode i en tæt løkke, varmer JIT op og rapporterer nanosekunder pr. operation, hvor støjen er fjernet.

Brug det til parsere, serialisering, sortering eller en hvilken som helst CPU-bundet hjælpefunktion, du kalder ofte.

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

Systemsporing med Perfetto

Systemsporing registrerer, hvad hver tråd og systemet foretog sig, billede for billede. Android Studios CPU-profiler kan optage et spor, og du kan også optage med adb og åbne det i Perfetto (ui.perfetto.dev).

Et spor viser de frygtede røde billeder, arbejdet på hovedtråden og den tid, der bruges på GPU'en. Det er det bedste enkeltværktøj til at diagnosticere hakken.

# 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

Brugerdefinerede sporingssektioner

Som standard viser spor frameworkets arbejde. Hvis du vil mærke din egen kode, skal du omslutte den med en navngiven sporingssektion. Navnene vises derefter som mærkede blokke i Perfetto, så det er nemt at få øje på steder med høj belastning.

Brug API'et androidx.tracing, så sektionerne vises i både debug- og benchmarkspor.

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

Sporing af tabte billeder under kørsel

Du har ikke altid en profiler tilkoblet. JankStats er et Jetpack-bibliotek, der rapporterer billeder med hakken fra den app, der kører, så du kan logge dem eller sende samlede data til analyse.

Det kobler sig på vinduet og kalder dig tilbage, hver gang et billede overskrider sit 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 }

Sådan læser du tallene: percentiler

Et enkelt gennemsnit skjuler problemerne. Hvis dit gennemsnitlige billede tager 10 ms, men 99-percentilen er 40 ms, har 1 % af billederne hakken, og brugerne mærker det. Se altid på P50, P90, P99 og ikke kun på gennemsnittet.

Benchmarks rapporterer disse tal for dig. Hjælpekoden nedenfor viser idéen med rå billedprøver.

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

En reproducerbar måleprocedure

Pålidelige tal kommer fra en disciplineret proces. Følg denne tjekliste hver gang:

  • Brug et release-/ikke-fejlfindingsbuild (R8 aktiveret).
  • Kør på en fysisk enhed, der er tilsluttet strøm, og med en stabil termisk tilstand.
  • Gentag scenariet flere gange, og rapportér medianen.
  • Ændr én ting ad gangen, og mål igen.
  • Sammenlign med en gemt baseline, så du kan dokumentere en forbedring.

Hvis du springer dette over, jagter du støj i stedet for at løse virkelige problemer.

Hvor tiden faktisk bruges

Det meste hakken i Android kommer fra et lille antal årsager. Når du kender dem, ved du, hvor du skal rette dine værktøjer hen:

  • Arbejde på hovedtråden: disk/netværk/JSON på UI-tråden.
  • For megen rekomposition: Compose tegner alt for meget igen.
  • Allokeringsuro: pauser på grund af affaldsindsamling.
  • Layoutgennemløb: dybt indlejrede layouts eller layouts, der måles gentagne gange.

De næste lektioner i dette kursus tager direkte fat på rekomposition, hukommelseslækager og opstart. Måling fortæller dig, hvad du skal løse først.

Hurtigt tjek

Du vil have en stabil og reproducerbar måling af, hvor lang tid din apps kolde opstart tager på en rigtig enhed over flere kørsler. Hvilket værktøj passer bedst?

Opsummering: Du kan nu måle

Du har lært at gøre performance synlig, før du ændrer noget:

  • Det 16 ms store framebudget afgør, om oplevelsen er flydende eller præget af hakken.
  • Android Studio Profiler viser CPU, hukommelse og energi i realtid.
  • Makro- og mikrobenchmarks giver reproducerbare tal.
  • Perfetto-spor og brugerdefinerede trace()-sektioner viser, hvor tiden bruges.
  • JankStats rapporterer hakken fra den app, der kører.
  • Læs P50/P90/P99, profilér release-builds på rigtige enheder, og ændr én ting ad gangen.

Nu anvender vi dette på en af de største kilder til hakken i Compose: rekomposition.

Gratis at komme i gang

Lær Kotlin med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
36
Lektioner
152

Ofte stillede spørgsmål

Er lektionen “Måling af ydeevne” gratis?

Ja — alle 3 lektioner i læringssporet Android Academy, inklusive “Måling af ydeevne”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Android Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Måling af ydeevne”?

Profilere, traces og benchmarks. Du øver dig i Android Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Android Academy?

Der kræves ingen tidligere erfaring. Android Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “Måling af ydeevne”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Android Academy-lektion?

Ja. Alle Android Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Måling af ydeevne
  2. Styr på recomposition
  3. Memory leaks og løsninger
  4. Opstart og baseline-profiler
← Tilbage til Android Academy