How to Implement an FPS Counter

· coding · Source ↗

TLDR

  • A rolling time-window of frame timestamps (fixed 1s duration) is the correct basis for an FPS counter; frame-count windows produce misleading graphs.

Key Takeaways

  • Method 1 (single frame) and Method 2 (N latest frames) are wrong: one is noisy, the other creates a self-referential window whose duration scales with the metric being measured.
  • Method 4 stores a queue of frame completion timestamps; pop any older than the window, divide count by window length for FPS.
  • Method 5 extends this by storing per-frame processing times, enabling average frame time, slowest frame, and standard deviation from the same structure.
  • Use SDL_GetPerformanceCounter or std::chrono::high_resolution_clock for sufficient timer precision; low-precision timers undermine all methods.
  • A circular buffer can replace the queue to avoid heap allocations mid-frame; size it beyond any expected burst.

Hacker News Comment Review

  • Commenters broadly agreed on the rolling window approach but pushed for exponential moving average (EMA) as a simpler constant-time/space alternative: alpha = 2/(n+1) gives smoothing equivalent to an n-sample moving average with no queue.
  • Several commenters noted FPS alone is insufficient for perceived performance; tracking low-percentile frame times (low1%, low0.1%) over a 10s window catches stutters the average hides, and color-coding the counter on dips is a practical shipped pattern.
  • A Vulkan-level caveat: present-to-present timing is not reliably available without VK_EXT_present_timing, and OS scheduler noise muddies even high-accuracy render timings, so any FPS counter is at best an estimate of render throughput, not true display cadence.

Notable Comments

  • @mightyham: EMA with alpha = 2/(n+1) matches an n-sample moving average with O(1) time and space, no queue needed.
  • @NL807: Last-frame FPS suits spike detection; median window suits perceived frame rate; mean window suits statistical frame rate – pick by use case.
  • @flohofwoe: Apply the smoothed frame duration to animation and game logic timing too, not just the display counter, or micro-stutter persists even with a clean FPS readout.

Original | Discuss on HN