Framerate

Durchschnittliche FPS

Eine reibungslose und stabile Framerate ist entscheidend für ein hochwertiges Spielerlebnis auf Android-Geräten. Bei der Messung der Spieleleistung sollten Sie die durchschnittliche FPS als Referenzwert verwenden, um ein grundlegendes Verständnis des Spielerlebnisses zu erhalten. Sie sollten Ihr Spiel so optimieren, dass es die durchschnittliche Framerate von 60 FPS erreicht, um ein optimales Spielerlebnis zu gewährleisten.

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

Auch bei einer reibungslosen durchschnittlichen Framerate von 60 FPS kann es bei einem Spiel zu gelegentlichen Rucklern, Mikrorucklern und unvorhersehbaren Eingabeverzögerungen kommen, was zu einem schlechten Spielerlebnis führt.

Daher ist die Framestabilität genauso wichtig wie die Verfolgung der durchschnittlichen Framerate. Hier sollten Sie die Messwerte für die P90- und P99-Framerate als konsistente Referenz bzw. als Indikator für Ruckler verwenden. Diese Messwerte erfassen das „Ende“ der Leistung, damit Sie die reibungslose Wiedergabe für die Spieler optimieren können.

Messwerte

  • Durchschnittliche FPS (Referenzwert): Dieser grundlegende Messwert bietet eine allgemeine Referenz für die Leistung Ihres Spiels. Er ist zwar ein Standard-Benchmark, aber bei der Durchschnittsberechnung können gelegentliche Framedrops und Mikroruckler nicht erkannt werden. Daher reicht er allein nicht aus, um das Spielerlebnis darzustellen.
  • P90-FPS (konsistente Referenzwert beim 10. Perzentil): Dieser Wert gibt an, dass 90 % Ihrer Frames diesen konsistenten Referenzwert überschritten haben und nur die langsamsten 10 % der Frames länger zum Rendern benötigt haben. Wenn Ihre P90-Framerate hoch ist und nahe am Durchschnitt liegt, läuft das Spiel für die überwiegende Mehrheit der Sitzungen konstant gut.
  • P99-FPS (Indikator für Ruckler beim 1. Perzentil): Dieser Wert gibt an, dass 99 % Ihrer Frames diesen Indikator für Ruckler überschritten haben. Er isoliert speziell die langsamsten 1 % der Frames. Dieser Messwert ist wichtig, um Mikroruckler, Verzögerungen beim Laden von Assets und plötzliche Spitzen beim Rendern von Assets zu erkennen, die sichtbare Ruckler verursachen.

Beispiele

Wenn Sie Ihre durchschnittliche FPS mit den P90- und P99-Messwerten vergleichen, können Sie das zugrunde liegende Verhalten eines Spiels genau diagnostizieren.

Szenario 1: Optimale Kurve (optimiertes Spiel)

  • Durchschnitt: 60 FPS (16,6 ms)
  • P90: 58 FPS (17,2 ms)
  • P99: 52 FPS (19,2 ms)
  • Analyse: Die Messwerte liegen nah beieinander. Das Spiel fühlt sich unglaublich reibungslos und konsistent an. 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)

  • Durchschnitt: 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. Der P99-Wert sinkt im Vergleich zum Durchschnitt nicht drastisch. Das deutet darauf hin, dass das System im Wesentlichen durch Grafikeinstellungen oder Auflösungsbeschränkungen überlastet ist. Das Spiel fühlt sich nicht ruckelig, sondern eher träge an. Wenn Sie die Grafikeinstellungen reduzieren, werden diese Messwerte in der Regel gleichmäßig erhöht.

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

  • Durchschnitt: 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 hervorragend aus, aber der P99-Wert deutet auf ein kritisches Problem hin. Ein P99-Wert von 66,6 ms bedeutet, dass das Spiel für mehrere Frames gleichzeitig komplett einfriert. Das deutet auf erhebliche Ausreißer hin, die in der Regel durch CPU-Engpässe, Verzögerungen beim Asset-Streaming (z. B. langsamer RAM oder Speicher) oder Ruckler durch die Shader-Kompilierung verursacht werden.

Messung

Es gibt zwei Methoden, um die durchschnittliche FPS, die P90-FPS und die P99-FPS effektiv zu messen. Die erste Methode besteht darin, Systemtraces mit dem Android Performance Analyzer (APA) zu analysieren, einem Tool zur Leistungsprofilierung. Die zweite Methode ist die Verwendung des vorhandenen Befehls adb dumpsys SurfaceFlinger --timestats.

1. Mit APA messen

Mit dem APA können Sie einen Systemtrace aufzeichnen und Framedaten genau mit SQL-Abfragen analysieren. So messen Sie Ihre Messwerte:

  1. Trace mit APA erfassen: Führen Sie Ihr Spiel aus und verwenden Sie APA, um einen Systemtrace während des Segments zu erfassen, das Sie analysieren möchten (z. B. ein Punkt während des Spiels, an dem Sie Framedrops vermuten). Sobald das Gerät verbunden und die Traceaufzeichnung abgeschlossen ist, werden die Tracedaten in die APA-Oberfläche geladen.

    Bildschirm zur Traceerfassung oder Bildschirm mit geladenem Trace
  2. Auf den Tab „SQL“ in APA klicken: Wenn der Bildschirm zur Traceanalyse geöffnet ist, klicken Sie im oberen oder seitlichen Navigationsbereich der Benutzeroberfläche auf den Tab SQL , um die Traceverarbeitungsumgebung zu öffnen, in der Sie die Daten direkt abfragen können.

  3. SQL-Abfrage auf dem Tab „SQL“ in APA einfügen: Kopieren Sie die folgende SQL-Abfrage und fügen Sie sie in das Eingabefeld für die Abfrage ein. Diese Abfrage identifiziert den SurfaceFlinger-Prozess, berechnet die Frameintervalle anhand der tatsächlichen Zeitstempel für die Anzeigeaktualisierung und leitet die durchschnittliche FPS, die niedrigsten 10 % der FPS (P90) und die niedrigsten 1 % der FPS (P99) ab.

    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 in der Nähe des Eingabefelds für die Abfrage auf die Schaltfläche Abfrage ausführen (oder das Ausführungssymbol). Sobald die Abfrageausführung abgeschlossen ist, 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 Bereich „Ergebnisse“ angezeigt.

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

2. Mit adb messen (dumpsys SurfaceFlinger)

Mit dem Befehl Android dumpsys surfaceflinger --timestats können Sie die durchschnittliche FPS, die P90-FPS und die P99-FPS effektiv messen. Dieses Tool liefert die durchschnittliche FPS und ein presentToPresent-Timinghistogramm für alle gerenderten Ebenen. Die presentToPresent-Zeit eines Frames ist das Intervall zwischen dem aktuellen Frame und dem vorherigen Frame, der gezeichnet wurde.

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 ausgeführt wurde, führen Sie den Befehl noch einmal mit dem Flag „dump“ aus, um die Informationen auszugeben:

    adb shell dumpsys SurfaceFlinger --timestats -dump
    
  3. Nach Ebene filtern: Die ausgegebenen Informationen enthalten Daten für alle Ebenen von SurfaceFlinger gerendert. Sie müssen den Abschnitt finden, der Ihrem Spiel entspricht, 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 durchschnittliche FPS für jede Ebene wird automatisch berechnet und direkt in der 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 Gesamtzahl der Frames und das presentToPresent Timinghistogramm analysieren, das in der Ausgabe enthalten ist.

    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 der kumulativen Verteilung) Angenommen,in Ihrer Spielsitzung wurden insgesamt 1.000 Frames aufgezeichnet. Um P90 und P99 zu ermitteln, berechnen Sie die Schwellenwerte in Millisekunden, bei denen die kumulative Anzahl der Frames 900 Frames (90%) bzw. 990 Frames (99%) erreicht, wobei Sie mit dem niedrigsten Millisekunden-Bucket beginnen.

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

    B. Implementierungslogik (Pseudocode) Wenn Sie diese Analyse mit einem Python-Skript oder einem Log-Parser automatisieren, kann die Logik zum Extrahieren von P90- und P99-Werten 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 weit verbreitete Leistungsprobleme in der Praxis hin. Eine Sitzung ist „langsam“, wenn mehr als 25% der Frames unter einen Schwellenwert fallen (z. B. 20 FPS). Dieser Messwert ist zwar nützlich, um kritische Probleme mit dem Build zu erkennen, kann aber allein kein hochwertiges und nachhaltiges Spielerlebnis garantieren. Ein Spiel kann den Schwellenwert für langsame Sitzungen vermeiden, aber trotzdem unter Mikrorucklern leiden, die ein reibungsloses 60-FPS-Erlebnis beeinträchtigen.

„Langsame Sitzung“ und „Framerate“ werden zwar beide aus den Frame Times abgeleitet, haben aber unterschiedliche Funktionen. Die Messwerte für die durchschnittliche FPS, die P90-FPS und die P99-FPS messen die Qualität und Nachhaltigkeit der Leistung und erkennen sofortige Drops und inkonsistente Geschwindigkeiten, die der Messwert für langsame Sitzungen möglicherweise übersieht.

Fazit

Eine erfolgreiche Leistungsoptimierung erfordert eine umfassende Strategie. Entwickler sollten langsame Sitzungen als primäres Radar verwenden, um erhebliche Leistungseinbußen zu erkennen, und dann die durchschnittliche FPS, die P90-FPS und die P99-FPS untersuchen, um die zugrunde liegenden Ursachen zu diagnostizieren und die tatsächliche Reibungslosigkeit des Spiels zu überprüfen. Durch die Einbindung dieser Messwerte können Sie sicherstellen, dass Ihre Anwendung ein durchweg nachhaltiges und außergewöhnliches Nutzererlebnis 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 anhaltende Zeiträume mit langsamem Rendering misst und meldet, was sich direkt auf das Nutzererlebnis auswirkt. Eine „langsame Sitzung“ ist eine Nutzersitzung, bei der mehr als 25% der Frames langsam sind (z. B. mehr als 50 ms dauern, was 20 FPS entspricht).
  • Android Developers: Optimize Game Performance: Hier finden Sie die zentrale Anlaufstelle für die Optimierung von Android-Spielen. Dieser umfassende Leitfaden enthält Best Practices und Profiling-Tools (wie APA und Perfetto), mit denen Sie die Gesamtleistung Ihres Spiels maximieren können.