Przechwytywanie danych analizy porównawczej

Pojęcia i implementacja Jetpack Compose

Dane to główny rodzaj informacji wyodrębnianych z testów porównawczych. Są one przekazywane do funkcji measureRepeated jako List, co pozwala określić wiele mierzonych danych jednocześnie. Do przeprowadzenia testu porównawczego wymagany jest co najmniej 1 rodzaj danych.

Ten fragment kodu rejestruje dane dotyczące czasu renderowania klatki i niestandardowej sekcji śladu:

Kotlin

benchmarkRule.measureRepeated(
    packageName = TARGET_PACKAGE,
    metrics = listOf(
        FrameTimingMetric(),
        TraceSectionMetric("RV CreateView"),
        TraceSectionMetric("RV OnBindView"),
    ),
    iterations = 5,
    // ...
)

Java

benchmarkRule.measureRepeated(
    TARGET_PACKAGE,     // packageName
    Arrays.asList(      // metrics
        new StartupTimingMetric(),
        new TraceSectionMetric("RV CreateView"),
        new TraceSectionMetric("RV OnBindView"),
    ),
    5,                  // Iterations
    // ...
);

W tym przykładzie RV CreateView i RV OnBindView to identyfikatory bloków możliwych do śledzenia, które są zdefiniowane w pliku RecyclerView. Kod źródłowy metody createViewHolder() jest przykładem tego, jak można definiować możliwe do śledzenia bloki we własnym kodzie.

StartupTimingMetric, TraceSectionMetric i FrameTimingMetric zostały szczegółowo opisane w dalszej części tego dokumentu. Pełną listę danych znajdziesz w podklasach Metric.

Wyniki testu porównawczego są wyświetlane w Android Studio, jak pokazano na rysunku 1. Jeśli zdefiniowano wiele danych, wszystkie są łączone w danych wyjściowych.

Wyniki TraceSectionMetric i FrameTimingMetric.
Rysunek 1. Wyniki dla: TraceSectionMetric i FrameTimingMetric.

StartupTimingMetric

StartupTimingMetric rejestruje dane o czasie uruchamiania aplikacji z tymi wartościami:

  • timeToInitialDisplayMs: czas od momentu, gdy system otrzyma intencję uruchomienia, do momentu, gdy wyrenderuje pierwszą klatkę docelowego elementu Activity.
  • timeToFullDisplayMs: czas, który upływa od momentu, gdy system otrzyma intencję uruchomienia, do momentu, gdy aplikacja zgłosi pełne wyrenderowanie za pomocą metody reportFullyDrawn(). Pomiar kończy się po wyrenderowaniu pierwszej klatki po wywołaniu reportFullyDrawn() lub zawierającej to wywołanie. Ten pomiar może być niedostępny na Androidzie 10 (API na poziomie 29) i starszych wersjach.

StartupTimingMetric wyświetla wartości minimalne, medianę i maksymalne z iteracji uruchamiania. Aby ocenić poprawę czasu uruchamiania, zawsze skupiaj się na wartościach mediany, ponieważ dają one najlepsze oszacowanie typowego czasu uruchamiania u użytkowników. Więcej informacji o czynnikach wpływających na czas uruchamiania aplikacji znajdziesz w artykule Czas uruchamiania aplikacji.

Wyniki StartupTimingMetric
Rysunek 2. StartupTimingMetric wynik.

FrameTimingMetric

FrameTimingMetric rejestruje informacje o czasie z klatek wygenerowanych przez test porównawczy, takich jak przewijanie lub animacja, i zwraca te wartości:

  • frameOverrunMs: czas, o jaki dana klatka przekroczyła termin. Liczby dodatnie oznaczają pominiętą klatkę, której towarzyszy widoczne zacinanie się lub przeskakiwanie. Liczby ujemne wskazują, o ile szybciej klatka została ukończona w stosunku do terminu sprzętowego podsystemu. Uwaga: te dane są dostępne tylko na urządzeniach z Androidem 12 (poziom interfejsu API 31) lub nowszym.
  • frameDurationCpuMs: czas potrzebny na wygenerowanie klatki przez procesor zarówno w wątku UI, jak i w RenderThread.

Te pomiary są zbierane w rozkładzie 50, 90, 95 i 99 centyla.

Więcej informacji o tym, jak identyfikować i poprawiać powolne klatki, znajdziesz w artykule o powolnym renderowaniu.

Wyniki FrameTimingMetric
Rysunek 3. FrameTimingMetric wynik.

TraceSectionMetric

TraceSectionMetric rejestruje liczbę wystąpień określonej sekcji logu czasu i bezwzględny czas jej wykonania. W przypadku śledzenia czasu wyświetla minimalny, średni i maksymalny czas w milisekundach.

Sekcja docelowego logu czasu jest definiowana przez wywołanie funkcji trace(sectionName) lub granice bloków niższego poziomu między Trace.beginSection(sectionName) a Trace.endSection() lub ich warianty asynchroniczne. Zawsze wybiera pierwsze wystąpienie sekcji śladu zarejestrowane podczas pomiaru. Domyślnie wyświetla tylko sekcje śledzenia z pakietu. Aby uwzględnić procesy spoza pakietu, ustaw targetPackageOnly = false.

Więcej informacji o śledzeniu znajdziesz w artykule Omówienie śledzenia systemu i Definiowanie zdarzeń niestandardowych.

TraceSectionMetric
Rysunek 4. TraceSectionMetric wynik.