Macrobenchmark metriklerini yakalama

Metrikler, karşılaştırmalarınızdan elde edilen temel bilgi türüdür. Bunlar, measureRepeated işlevine List olarak iletilir. Bu sayede, birden fazla ölçülen metriği aynı anda belirtebilirsiniz. Karşılaştırmanın çalışması için en az bir metrik türü gereklidir.

Aşağıdaki kod snippet'i, Jetpack Compose geç yüklenen düzen arayüzü için kare süresi ve özel izleme bölümü metriklerini yakalar:

@OptIn(ExperimentalMetricApi::class)
    @Test
    fun scrollComposeList() {
        benchmarkRule.measureRepeated(
            // [START_EXCLUDE]
            packageName = TARGET_PACKAGE,
            metrics = listOf(
                FrameTimingMetric(),
                // Measure power usage. This is supported on Pixel 6 and later.
                PowerMetric(PowerMetric.Type.Power(
                    mapOf(
                        PowerCategory.CPU to PowerCategoryDisplayLevel.TOTAL,
                        PowerCategory.DISPLAY to PowerCategoryDisplayLevel.TOTAL,
                        PowerCategory.GPU to PowerCategoryDisplayLevel.TOTAL,
                        PowerCategory.NETWORK to PowerCategoryDisplayLevel.TOTAL,
                    )
                )),
                // Measure custom trace sections by name EntryRow (which is added to the EntryRow composable).
                // Mode.Sum measures combined duration and also how many times it occurred in the trace.
                // This way, you can estimate whether a composable recomposes more than it should.
                TraceSectionMetric("EntryRowCustomTrace", TraceSectionMetric.Mode.Sum),
                // This trace section takes into account the SQL wildcard character %,
                // which can find trace sections without the full name.
                // This way, you can measure composables produced by the composition tracing
                // and measure how long they took and how many times they recomposed.
                // WARNING: This metric only shows results when running with composition tracing, otherwise it won't be visible in the outputs.
                TraceSectionMetric("%EntryRow%", TraceSectionMetric.Mode.Sum),
            ),
            // Try switching to different compilation modes to see the effect
            // it has on frame timing metrics.
            compilationMode = CompilationMode.None(),
            startupMode = StartupMode.WARM, // restarts activity each iteration
            iterations = DEFAULT_ITERATIONS,
            // [END_EXCLUDE]
            setupBlock = {
                uiAutomator {
                    // Before starting to measure, navigate to the UI to be measured.
                    startIntent(Intent("$packageName.COMPOSE_ACTIVITY"))
                }
            }
        ) {
            uiAutomator {
                onElement { isScrollable }.fling(Direction.DOWN)
            }
        }
    }

Aşağıdaki örnekte EntryRowCustomTrace, standart Kotlin trace(sectionName) { ... } blok sarmalayıcısı kullanılarak composable öğe katmanlarında tanımlanan özel bir izleme bölümünü temsil etmektedir. TraceSectionMetric için veri sağlamak istiyorsanız uygulamanızın üretim kod tabanındaki hedef kullanıcı arayüzü bileşenlerini standart Jetpack çalışma zamanı trace blok sarmalayıcısıyla sarmalamanız gerekir:

@Composable
private fun EntryRow(entry: Entry, modifier: Modifier = Modifier) = trace("EntryRowCustomTrace") {
    Card(modifier = modifier) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            Text(
                text = entry.contents,
                modifier = Modifier
                    .padding(16.dp)
                    .wrapContentSize()
            )

            Spacer(modifier = Modifier.weight(1f))

            Checkbox(
                checked = false,
                onCheckedChange = {},
                modifier = Modifier.padding(16.dp)
            )
        }
    }
}

Karşılaştırma sonuçları, Şekil 1'de gösterildiği gibi doğrudan Android Studio'daki Benchmark terminal sekmesine gönderilir. Birden fazla metrik tanımlanırsa hesaplanan tüm veri noktaları özet penceresinde birleştirilir.

TraceSectionMetric ve FrameTimingMetric sonuçları.
Şekil 1. Modern bir Compose düzeni için TraceSectionMetric ve FrameTimingMetric'in birleştirilmiş konsol sonuçları.

StartupTimingMetric, FrameTimingMetric, TraceSectionMetric ve PowerMetric aşağıda ayrıntılı olarak açıklanmıştır. Kullanılabilir karşılaştırma metriklerinin tam listesi için API referansındaki Metric alt sınıflarına bakın.

StartupTimingMetric

StartupTimingMetric, uygulama başlatma zamanlaması metriklerini aşağıdaki değerlerle yakalar:

  • timeToInitialDisplayMs: Sistemin başlatma intent'ini alması ile hedef ekranın ilk karesini oluşturması arasında geçen süre.
  • timeToFullDisplayMs: Sistemin bir başlatma intent'i almasından, uygulamanın dahili platform raporlama mekanizmalarını kullanarak tamamen çizildiğini bildirmesine kadar geçen süre. Ölçüm, tamamen çizilmiş sinyalden sonraki veya bu sinyali içeren ilk karenin oluşturulması tamamlandığında durur.

StartupTimingMetric, başlangıç iterasyonlarından minimum, medyan ve maksimum değerleri verir. Başlatma süresindeki iyileşmeyi değerlendirirken her zaman ortanca değerlere odaklanın. Bu değerler, tipik kullanıcı başlatma sürelerinin en iyi tahminini sağlar.

Compose öncelikli bir mimaride activity.reportFullyDrawn yöntemini manuel olarak çağırmaya çalışmayın. Bunun yerine, eşzamansız ağ verilerinizin veya karmaşık kullanıcı arayüzü durumlarınızın oluşturma işleminin ne zaman tamamlandığını Macrobenchmark'a otomatik olarak bildirmek için ekran composable'larınızda Compose için güvenli eşzamansız yardımcı programları (ReportDrawn, ReportDrawnWhen veya ReportDrawnAfter) kullanın.

Başlatma performansını analiz etme ve optimize etme hakkında daha fazla bilgi için Uygulama başlatma süresi başlıklı makaleyi inceleyin.

FrameTimingMetric

FrameTimingMetric, bir karşılaştırma yolculuğu tarafından üretilen karelerden (ör. bir listeyi kaydırma veya karmaşık bir kullanıcı arayüzü yerleşimi animasyonu) kesin zamanlama bilgilerini yakalar ve aşağıdaki teşhis değerlerini verir:

  • frameOverrunMs: Belirli bir karenin son tarihini kaçırdığı süre. Pozitif sayılar, görünür takılma veya titremenin eşlik ettiği kare düşüşünü gösterir. Negatif sayılar, bir karenin alt sistem donanım son tarihine göre ne kadar hızlı tamamlandığını gösterir. Not: Bu metrik yalnızca Android 12 (API düzeyi 31) ve sonraki sürümlerde kullanılabilir.
  • frameDurationCpuMs: Karenin hem ana uygulama kullanıcı arayüzü iş parçacığında hem de Compose RenderThread'da CPU üzerinde aktif olarak üretildiği süre.

Bu ölçümler 50., 90., 95. ve 99. yüzdelik dilimlerin dağılımında toplanır:

frameDurationCpuMs P50 3.5, P90 6.0, P95 6.4, P99 11.0
frameOverrunMs P50 -11.6, P90 -7.2, P95 -7.1, P99 -1.2

Jetpack Compose düzen hiyerarşilerini optimize ederken en düşük performans gösteren karelerinize (P95 ve P99 sınırları) bakın. frameOverrunMs, yüksek yüzdelik dilimlerde pozitif tam sayılara yükselirse yeniden oluşturma işlemleri, yoğun kaydırma animasyonları sırasında ana iş parçacığını durduruyor demektir.

Yavaş kareleri belirleme ve çözme hakkında daha ayrıntılı bilgi için Jetpack Compose Performansı başlıklı makaleyi inceleyin.

TraceSectionMetric

TraceSectionMetric, belirli bir izleme bölümünün kaç kez gerçekleştiğini ve yürütülmesinin ne kadar sürdüğünü gösterir. Zaman takibi için minimum, medyan ve maksimum süreleri milisaniye cinsinden verir. Hedef izleme bölümü, trace(sectionName) işlev çağrısı veya Trace.beginSection(sectionName) ile Trace.endSection() arasındaki alt düzey blok sınırları ya da bunların eş zamansız varyantları tarafından tanımlanır.

EntryRowCustomTraceCount min 20.0, median 28.0, max 50.0
EntryRowCustomTraceSumMs min 34.9, median 44.4, max 66.6

Varsayılan olarak metrik, yalnızca doğrudan kendi uygulama paketi ikili dosyalarınızdan derlenen izleme bölümlerini döndürür. Uygulamanızın paket sınırının dışından kaynaklanan işlemleri dahil etmek için targetPackageOnly = false özelliğini ayarlayın.

Jetpack Compose Çalışma Zamanı İzleme ile çalışırken oluşturma izlemeyi etkinleştirerek manuel izleme sarmalayıcıları yazmadan sistem izleme grafiklerinizde ayrı ayrı composable işlevleri gösterebilirsiniz.

Hedef uygulamanıza androidx.compose.runtime:runtime-tracing bağımlılığını eklemek manuel profil oluşturucu izleri için yeterli olsa da bu izleri bir Macrobenchmark çalıştırması içinde programatik olarak yakalamak için karşılaştırma modülünüzde ek yapılandırma gerekir.

Kurulum talimatlarının tamamı için Jetpack Macrobenchmark ile iz yakalama başlıklı makaleyi inceleyin.

PowerMetric

PowerMetric, Macrobenchmark çalıştırmanız süresince güç veya enerjideki değişimi yakalar. Seçilen her kategori, ölçülebilir donanım bileşenlerine ayrılırken seçilmeyen kategoriler "seçilmemiş" grubunda toplanır.

Donanım Gereksinimi: Bu metrikler, uygulama başına hesaplamalar yerine sistem genelindeki tüketimi ölçer. Bu nedenle, veri toplama işlemi fiziksel Google Pixel 6, Pixel 6 Pro ve daha yeni fiziksel cihazlarla sınırlıdır.

Metrik, kategori başına iki ölçüm sonucu verir:

  • power<category>Uw: Bu kategorideki testiniz süresince tüketilen güç miktarı (mikrovat cinsinden ölçülür).
  • energy<category>Uws: Bu kategorideki testiniz süresince birim zaman başına aktarılan toplam enerji miktarı (mikrovat-saniye cinsinden ölçülür).

Kategoriler şunlardır:

  • CPU
  • DISPLAY
  • GPU
  • GPS
  • MEMORY
  • MACHINE_LEARNING
  • NETWORK
  • UNCATEGORIZED

CPU gibi bazı kategorilerde, diğer işlemler tarafından yapılan işleri kendi uygulamanız tarafından yapılan işlerden ayırmak zor olabilir. Müdahaleyi en aza indirmek için gereksiz uygulamaları ve hesapları kaldırın veya kısıtlayın.

powerCategoryCpuUw min 300.2, median 346.1, max 519.6
powerCategoryDisplayUw min 319.8, median 325.8, max 329.7
powerCategoryGpuUw min 18.8, median 23.3, max 36.9
powerCategoryNetworkUw min 97.3, median 123.3, max 681.3
powerTotalUw min 1234.8, median 1316.6, max 2112.4
powerUnselectedUw       min  483.3,  median  512.6,  max  561.7

Temel alt sistemler analiz ediliyor

PowerMetric, sağlanan güç kategorileri için testiniz süresince güç veya enerjideki değişimi yakalar. Seçtiğiniz her kategori, ölçülebilir alt bileşenlerine ayrılır ve seçilmeyen kategoriler "seçilmeyen" metriğine eklenir.

Terminal çıkışları, istediğiniz yapılandırmayla eşlenir:

  • powerCategoryCpuUw: Testiniz süresince CPU tarafından tüketilen güç miktarı.
  • powerCategoryGpuUw: Testiniz süresince GPU tarafından tüketilen güç miktarı.
  • powerUnselectedUw: Başlatma haritanızda açıkça istenmeyen tüm mevcut donanım kategorileri tarafından tüketilen toplam güç.

Çalışma sırasında donanım raylarında düzensiz veri artışlarını önlemek için ekran parlaklığını sabit bir değere kilitleyin, cihaz sıcaklığını sabit tutun ve Macrobenchmark döngüsünü başlatmadan önce rakip arka plan işlemlerini kapatın.

Ek kaynaklar

İçerik görüntüleme