Framerate

Durchschnittliche FPS

Eine flüssige und stabile Framerate ist entscheidend für eine hochwertige Gaming-Erfahrung auf Android-Geräten. Bei der Messung der Spieleleistung sollten Sie die durchschnittlichen FPS als Referenzwert verwenden, um ein grundlegendes Verständnis der Leistung zu erhalten. Sie sollten Ihr Spiel so optimieren, dass die durchschnittliche Bildrate von 60 FPS erreicht wird, um ein optimales Spielerlebnis zu bieten.

P90- und P99-FPS für Stabilität

Auch wenn ein Spiel durchschnittlich 60 fps erreicht, kann es zu gelegentlichen Rucklern, Mikrorucklern und unvorhersehbaren Eingabeverzögerungen kommen, was zu einer schlechten Spielerfahrung führt.

Die Stabilität der Frames ist also genauso wichtig wie die durchschnittliche Framerate. Hier sollten Sie die Messwerte für die P90- und P99-Framerate als konsistente Baseline bzw. als Indikator für Ruckeln messen. Diese Messwerte erfassen das „Ende“ der Leistung, damit Sie die reibungslose Nutzung für die Spieler optimieren können.

Messwerte

  • Durchschnittliche FPS (Baseline): Dieser grundlegende Messwert bietet eine allgemeine Baseline für die Leistung Ihres Spiels. Obwohl es sich um einen Standard-Benchmark handelt, können durch die Durchschnittsberechnung zeitweilige Frame-Drops und Mikroruckler nicht erkannt werden. Daher reicht er allein nicht aus, um die Spielerfahrung darzustellen.
  • P90 FPS (einheitlicher Referenzwert beim 10. Perzentil): Dieser Wert gibt an, dass 90 % Ihrer Frames diesen einheitlichen Referenzwert überschritten haben und nur die langsamsten 10 % der Frames länger zum Rendern gebraucht haben. Wenn die P90-Bildrate hoch und nah am Durchschnitt liegt, läuft das Spiel für den Großteil der Sitzung konstant gut.
  • P99 FPS (Stotterindikator beim 1. Perzentil): Dieser Wert gibt an, dass 99 % Ihrer Frames diesen Stotterindikator überschritten haben. Dabei werden die langsamsten 1 % der Frames isoliert. Dieser Messwert ist wichtig, um Mikrostottern, Verzögerungen beim Laden von Assets und plötzliche Rendering-Spitzen mit vielen Assets zu erkennen, die sichtbare Ruckler verursachen.

Beispiele

Wenn Sie Ihre durchschnittliche FPS mit den Messwerten für das 90. und 99. Perzentil vergleichen, können Sie das zugrunde liegende Verhalten eines Spiels genau diagnostizieren.

Szenario 1: Optimale Kurve (optimiertes Spiel)

  • Durchschnittlich: 60 FPS (16,6 ms)
  • P90: 58 FPS (17,2 ms)
  • P99: 52 FPS (19,2 ms)
  • Analyse: Die Messwerte sind eng gruppiert. Das Spiel läuft unglaublich flüssig und stabil. Es gibt keine Mikroruckler und selbst die schlechtesten 1% der Frames sind für das menschliche Auge kaum wahrnehmbar.

Szenario 2: Engpass bei der Last (CPU-/GPU-gebunden)

  • Durchschnittlich: 45 FPS (22,2 ms)
  • P90: 40 FPS (25,0 ms)
  • P99: 38 FPS (26,3 ms)
  • Analyse: Die durchschnittliche Framerate ist niedriger, aber konstant. P99 sinkt im Vergleich zum Durchschnitt nicht drastisch. Dies weist darauf hin, dass das System im Grunde durch Grafikeinstellungen oder Auflösungsbeschränkungen überfordert ist. Das Spiel ruckelt nicht, sondern fühlt sich eher träge an. Wenn Sie die Grafikeinstellungen verringern, werden diese Messwerte in der Regel gleichmäßig erhöht.

Szenario 3: Instabile 60 FPS (Shader-Kompilierung / Asset-Streaming-Ruckler)

  • Durchschnittlich: 60 FPS (16,6 ms)
  • P90: 45 FPS (22,2 ms)
  • P99: 15 FPS (66,6 ms)
  • Analyse: Dies ist das Worst-Case-Szenario. Die durchschnittliche Framerate sieht zwar sehr gut aus, aber der P99-Wert weist auf ein schwerwiegendes Problem hin. Ein P99-Wert von 66,6 ms bedeutet, dass das Spiel für mehrere Frames gleichzeitig vollständig einfriert. Dies deutet auf schwerwiegende Ausreißer hin, die in der Regel durch CPU-Engpässe, Verzögerungen beim Asset-Streaming (z. B. langsamer RAM oder Speicher) oder Ruckler aufgrund der Shader-Kompilierung verursacht werden.

Messung

Um durchschnittliche FPS, P90-FPS und P99-FPS effektiv zu messen, können Sie die folgenden beiden Methoden verwenden. Bei der ersten Methode werden System-Traces mit dem Android Performance Analyzer (APA) analysiert, einem Tool zur Leistungsprofilierung. Bei der zweiten Methode wird der vorhandene adb dumpsys SurfaceFlinger --timestats-Befehl verwendet.

1. Messung mit APA

Mit der APA können Sie einen System-Trace aufzeichnen und Framedaten mithilfe von SQL-Abfragen genau analysieren. So messen Sie Ihre Messwerte:

  1. Trace mit APA aufzeichnen: Führen Sie Ihr Spiel aus und verwenden Sie APA, um während des zu analysierenden Segments einen System-Trace aufzuzeichnen (z. B. an einer Stelle im Spiel, an der Sie Frame-Drops vermuten). Sobald das Gerät verbunden ist und die Aufzeichnung des Traces abgeschlossen ist, werden die Trace-Daten in die APA-Benutzeroberfläche geladen.

    Bildschirm für die Trace-Aufzeichnung oder der geladene Trace-Bildschirm
  2. In APA auf den Tab „SQL“ klicken: Wenn der Bildschirm für die Trace-Analyse geöffnet ist, klicken Sie in der oberen oder seitlichen Navigation der Benutzeroberfläche auf den Tab SQL, um die Trace-Prozessor-Umgebung zu öffnen, in der Sie die Daten direkt abfragen können.

  3. SQL-Abfrage auf dem Tab „APA SQL“ einfügen: Kopieren Sie die folgende SQL-Abfrage und fügen Sie sie in das Abfrageeingabefeld ein. Mit dieser Abfrage wird der SurfaceFlinger-Prozess identifiziert, die Frame-Intervalle werden anhand der tatsächlichen Zeitstempel für die Display-Aktualisierung berechnet und die durchschnittliche FPS, die untersten 10% (P90) der FPS und die untersten 1% (P99) der FPS werden abgeleitet.

    WITH target_process AS (
    -- 1. Get SurfaceFlinger process ID where frames were identified in debugging step 3
    SELECT upid
    FROM process
    WHERE name = '/system/bin/surfaceflinger'
    ),
    actual_present_times AS (
    -- 2. Calculate the hardware display timestamps when SurfaceFlinger actually updated the screen
    SELECT
        (ts + dur) AS present_ts
    FROM actual_frame_timeline_slice
    WHERE upid IN (SELECT upid FROM target_process)
        AND dur > 0
    ),
    present_intervals AS (
    -- 3. Calculate intervals between physical screen refreshes
    SELECT
        (LEAD(present_ts) OVER (ORDER BY present_ts ASC) - present_ts) / 1000000.0 AS p2p_ms
    FROM actual_present_times
    ),
    valid_intervals AS (
    -- 4. Filter for valid frame intervals
    SELECT p2p_ms
    FROM present_intervals
    WHERE p2p_ms IS NOT NULL AND p2p_ms > 0
    ),
    ordered_frames AS (
    -- 5. Sort in ascending order to calculate percentiles
    SELECT
        p2p_ms,
        ROW_NUMBER() OVER (ORDER BY p2p_ms ASC) AS row_num,
        COUNT(1) OVER () AS total_frames
    FROM valid_intervals
    )
    -- 6. Output final metrics
    SELECT
    (SELECT COUNT(1) FROM valid_intervals) AS total_presented_frames,
    ROUND(1000.0 / NULLIF((SELECT AVG(p2p_ms) FROM valid_intervals), 0), 2) AS average_fps,
    ROUND(1000.0 / NULLIF((SELECT p2p_ms FROM ordered_frames WHERE row_num = CAST(total_frames * 0.90 AS INT)), 0), 2) AS low_10_fps,
    ROUND(1000.0 / NULLIF((SELECT p2p_ms FROM ordered_frames WHERE row_num = CAST(total_frames * 0.99 AS INT)), 0), 2) AS low_1_fps;
    
  4. Auf „Abfrage ausführen“ klicken: Klicken Sie neben dem Abfrageeingabefeld auf den Button Abfrage ausführen (oder das Ausführungssymbol). Sobald die Abfrage ausgeführt wurde, werden die gemessenen Gesamtframes (total_presented_frames), die durchschnittliche Framerate (average_fps), die niedrigsten 10% der FPS (low_10_fps) und die niedrigsten 1% der FPS (low_1_fps) in einer Tabelle im Ergebnisbereich angezeigt.

    Bildschirm mit der ausgeführten SQL-Abfrage und den vier resultierenden Messwerten in einer Tabelle

2. Mit adb messen (dumpsys SurfaceFlinger)

Um die durchschnittliche FPS, P90 und P99 effektiv zu messen, können Sie den Befehl dumpsys surfaceflinger timestats von Android verwenden. Dieses Tool bietet die durchschnittliche FPS und ein presentToPresent-Zeitachsendiagramm für alle gerenderten Ebenen. Die presentToPresent-Zeit eines Frames ist das Intervall zwischen dem Zeichnen des aktuellen Frames und des vorherigen Frames.

Hier finden Sie eine Schritt-für-Schritt-Anleitung zum Erfassen und Berechnen dieser Messwerte für Ihr Spiel:

  1. Erfassung starten: Führen Sie den folgenden Befehl mit den Flags „enable“ und „clear“ aus, um mit der Erfassung von Informationen zu beginnen:

    adb shell dumpsys SurfaceFlinger --timestats -clear -enable
    
  2. Informationen ausgeben: Wenn das Spiel lange genug gespielt wurde, führen Sie den Befehl noch einmal mit dem Dump-Flag aus, um die Informationen auszugeben:

    adb shell dumpsys SurfaceFlinger --timestats -dump
    
  3. Nach Ebene filtern: Die ausgegebenen Informationen enthalten Daten für alle von SurfaceFlinger gerenderten Ebenen. Sie müssen den Abschnitt für Ihr Spiel finden, indem Sie nach layerName filtern (z. B. layerName = SurfaceView[com.example.yourgame...]).

    layerName = SurfaceView[com.google.test/com.devrel.MainActivity]@0(BLAST)#132833
    
  4. Durchschnittliche FPS ermitteln: Die durchschnittlichen FPS für jede Ebene werden automatisch berechnet und direkt in der Dump-Ausgabe angezeigt (z. B. averageFPS = 30.179).

    ...
    averageFPS = 30.179
    ...
    
  5. P90- und P99-FPS berechnen: Um die P90- und P99-Messwerte zu ermitteln, müssen Sie die Gesamtanzahl der Frames und das im Dump enthaltene presentToPresent-Timing-Histogramm analysieren.

    totalFrames = 1000
    ...
    presentToPresent histogram is as below:
    0ms=0 1ms=0 2ms=0 3ms=0 4ms=0 5ms=0 6ms=0 7ms=0 8ms=0 9ms=0 10ms=0 11ms=0 12ms=0
    13ms=0 14ms=0 15ms=0 16ms=850 17ms=0 18ms=0 19ms=0 20ms=0 21ms=0 22ms=0 23ms=0
    24ms=0 25ms=0 26ms=0 27ms=0 28ms=0 29ms=0 30ms=0 31ms=0 32ms=0 33ms=100 34ms=0
    36ms=0 38ms=0 40ms=0 42ms=0 44ms=0 46ms=0 48ms=0 50ms=35 54ms=0 58ms=0 62ms=0
    66ms=10 70ms=0 74ms=0 78ms=0 82ms=0 86ms=0 90ms=0 94ms=0 98ms=0 102ms=5 106ms=0
    110ms=0 114ms=0 118ms=0 122ms=0 126ms=0 130ms=0 134ms=0 138ms=0 142ms=0 146ms=0
    150ms=0 200ms=0 250ms=0 300ms=0 350ms=0 400ms=0 450ms=0 500ms=0 550ms=0 600ms=0
    650ms=0 700ms=0 750ms=0 800ms=0 850ms=0 900ms=0 950ms=0 1000ms=0
    

    A. Konzeptionelles Beispiel (Tabelle mit kumulativer Verteilung) Angenommen,in Ihrer Spielsitzung wurden insgesamt 1.000 Frames aufgezeichnet. Um P90 und P99 zu ermitteln, berechnen Sie die Millisekunden-Grenzwerte, bei denen die kumulative Anzahl der Frames 900 Frames (90%) bzw. 990 Frames (99%) erreicht. Dabei wird vom niedrigsten Millisekunden-Bucket aufwärts gezählt.

    Frame Time (ms) Anzahl der Frames (Histogramm) Kumulative Anzahl von Frames Perzentilstatus / Berechnung
    16 ms 850 850 85,0%
    33 ms 100 950 95,0%
    (P90-Ziel von 900 erreicht! → 1000/33 = 30,3 fps)
    50 ms 35 985 98,5%
    66 ms 10 995 99,5%
    (P99-Ziel von 990 erreicht! → 1000/66 = 15,1 FPS)
    102 ms 5 1.000 100 %

    B. Implementierungslogik (Pseudocode) Wenn Sie diese Analyse mit einem Python-Skript oder Log-Parser automatisieren, kann die Logik zum Extrahieren der P90- und P99-Werte aus dem Histogramm so implementiert werden:

    # Define target thresholds based on total frame count
    p90_target = totalFrames * 0.90
    p99_target = totalFrames * 0.99
    
    cumulative_frames = 0
    p90_fps = None
    p99_fps = None
    
    # Iterate through the parsed SurfaceFlinger histogram data (sorted by millisecond)
    for ms_bucket, frame_count in present_to_present_histogram:
        cumulative_frames += frame_count
    
        # Capture P90 when cumulative frames cross the 90% threshold
        if p90_fps is None and cumulative_frames >= p90_target:
            p90_fps = 1000 / ms_bucket
    
        # Capture P99 when cumulative frames cross the 99% threshold
        if p99_fps is None and cumulative_frames >= p99_target:
            p99_fps = 1000 / ms_bucket
            break # Optimization: stop iterating once both targets are found
    
  6. Erfassung beenden: Nachdem Sie alle erforderlichen Informationen erfasst haben, sollten Sie die Zeitstatistiken mit dem Flag „disable“ deaktivieren:

    adb shell dumpsys SurfaceFlinger --timestats -disable
    

Langsame Sitzungen

Langsame Sitzungen weisen auf weitverbreitete Leistungsprobleme in der Praxis hin. Eine Sitzung gilt als „langsam“, wenn mehr als 25% der Frames unter einen bestimmten Grenzwert fallen (z. B. 20 fps). Dieser Messwert ist zwar nützlich, um kritische Probleme im Build zu erkennen, allein kann er jedoch keine qualitativ hochwertige, nachhaltige Nutzererfahrung garantieren. Ein Spiel kann den Schwellenwert für langsame Sitzungen vermeiden, aber trotzdem Mikroruckler aufweisen, die ein flüssiges Spielerlebnis mit 60 fps beeinträchtigen.

„Langsame Sitzung“ und „Frame-Rate“ werden zwar beide aus Frame-Zeiten abgeleitet, haben aber unterschiedliche Funktionen. Die Messwerte für die durchschnittliche Framerate sowie die Framerate für P90 und P99 messen die Qualität und Nachhaltigkeit der Leistung. Sie erkennen sofortige Einbrüche und inkonsistente Raten, die beim Messwert für langsame Sitzungen möglicherweise übersehen werden.

Fazit

Für eine erfolgreiche Leistungsoptimierung ist eine umfassende Strategie erforderlich. Entwickler sollten langsame Sitzungen als primären Indikator für erhebliche Leistungseinbußen verwenden und dann die durchschnittliche FPS, P90 und P99 untersuchen, um die zugrunde liegenden Ursachen zu ermitteln und die tatsächliche Flüssigkeit des Gameplays zu überprüfen. Durch die Einbindung dieser Messwerte können Sie dafür sorgen, dass Ihre Anwendung eine durchweg nachhaltige und außergewöhnliche Nutzererfahrung bietet.

Zusätzliche Ressourcen

Weitere Informationen zu erweiterten Profiling-Techniken, zur Implementierung der Frame Pacing API und zu enginespezifischen Optimierungsstrategien finden Sie in der offiziellen Android-Entwicklerdokumentation:

  • Android Vitals: Langsame Sitzungen: Hier erfahren Sie, wie Google Play längere Zeiträume mit langsamem Rendern misst und meldet, die sich direkt auf die Nutzerfreundlichkeit auswirken. Eine „langsame Sitzung“ ist eine Nutzersitzung, bei der mehr als 25% der Frames langsam sind (z. B. länger als 50 ms dauern, was 20 fps entspricht).
  • Android Developers: Optimize Game Performance: Hier findest du den zentralen Hub für die Optimierung von Android-Spielen. Dieser umfassende Leitfaden enthält Best Practices und Profiling-Tools wie APA und Perfetto, mit denen du die Gesamtleistung deines Spiels maximieren kannst.