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 die durchschnittliche Framerate von 60 FPS erreicht wird, 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 messen. Diese Messwerte erfassen das „Ende“ der Leistung, damit Sie die Reibungslosigkeit des Spielerlebnisses optimieren können.

Messwerte

  • Durchschnittliche FPS (Referenzwert): Dieser grundlegende Messwert bietet eine allgemeine Referenz für die Leistung Ihres Spiels. Obwohl es sich um einen Standard-Benchmark handelt, können gelegentliche Framerate-Einbrüche und Mikroruckler aufgrund der Durchschnittsberechnung nicht erkannt werden. Daher reicht dieser Messwert 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 und nah 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. Dabei werden die langsamsten 1 % der Frames isoliert. 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 die 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 die 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 einheitlich 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 aufgrund der Shader-Kompilierung verursacht werden.

Messung

Um die durchschnittliche FPS, den P90- und den P99-Wert effektiv zu messen, können Sie den Befehl „Android dumpsys surfaceflinger timestats“ verwenden. 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.

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 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 , die von SurfaceFlinger gerendert werden. 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 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 Werte für „totalFrames“ und das presentToPresent Timinghistogramm in der Ausgabe 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 der kumulativen Verteilung) Angenommen,in Ihrer Spielsitzung wurden insgesamt 1.000 Frames erfasst. Um den P90- und den P99-Wert zu ermitteln, berechnen Sie die Schwellenwerte in Millisekunden, bei denen die kumulative Anzahl der Frames 900 Frames (90%) bzw. 990 Frames (99%) erreicht. Zählen Sie dazu von der niedrigsten Millisekundengruppe aufwärts.

    Frame-Zeit (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 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 Erfassung von 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 im 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 Spielerlebnis mit 60 FPS beeinträchtigen.

Obwohl beide Messwerte aus den Frame-Zeiten abgeleitet werden, haben „Langsame Sitzung“ und „Framerate“ 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 Einbrüche 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 Integration 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 alle Informationen zur Optimierung von Android-Spielen. Diese umfassende Anleitung enthält Best Practices und Profiling-Tools (z. B. AGI und Perfetto), mit denen Sie die Gesamtleistung Ihres Spiels maximieren können.