Sign in to follow this  
wicked357

How accurate is my FPS class?

Recommended Posts

I just put together this class that calculates the fps and I was wondering how accurate is it exactly if you can tell by this code. Any suggestions would be appreciated.
#include <stdio.h>

class FramePerSecond
{
public:
	FramePerSecond();
	~FramePerSecond();
	void calculateFPS();
	char* getFPS();
private:
	int m_iFps;
	char m_cFpsStr[55];
	float m_fTime;
	float m_fLastTime;
};

FramePerSecond::FramePerSecond()
{
	m_iFps			= 0;
	m_cFpsStr[55]	= 0;
	m_fTime			= 0.0f;
	m_fLastTime		= 0.0f;
}

FramePerSecond::~FramePerSecond()
{
}

void FramePerSecond::calculateFPS()
{
	m_fTime = GetTickCount() * 0.001f;

	if(m_fTime - m_fLastTime > 1.0f)
	{
		m_fLastTime = m_fTime;

		sprintf_s(m_cFpsStr, "FPS: %d", m_iFps);

		m_iFps = 0;
	}
	else
		m_iFps++;
}

char* FramePerSecond::getFPS()
{
	return m_cFpsStr;
}

Share this post


Link to post
Share on other sites
Well, the accuracy is going to be determined by your clock source, so in this case GetTickCount. You can learn about its resolution by checking MSDN.

You're using it to determine when a full second is elapsed, so its resolution is sufficient. If you wanted more, there is QueryPerformanceCounter, along with its wonderful caveats.

There are also other methods apart from counting frames over a one second period if you wanted to explore them. You can maintain a sliding window of frame times and average them over a range of seconds.


General implementation things:

Why are you converting the count returned by GetTickCount from ms to s? If you use ms directly, there's no need for floating-point values.

If a full second has elapsed, calculateFPS doesn't increment the frame counter before formatting the frame count to the FPS text and resetting it - you're missing a frame here. You should just always increment the frame count when entered calculateFPS regardless of how much time has elapsed.

Why are you storing m_fTime as a member variable?


General C++ things:

  • No need to define or implement a deconstructor, the compiler's version will be fine.
  • Use initialization lists in your constructor.
  • You are going out of bounds when you do m_cFpsStr[55] = 0 in your constructor. You should be using 54, or even better, 0, or even betterer, std::strings, see below.
  • Don't use C-style strings. Use std::string and std::ostringstream.
  • Better yet, don't mix the string formatting in with the FPS counter. They are seperate tasks. If you need to convert the FPS to a string for rendering, that is something else's problem, not the FPS counter object's. Instead, return the FPS as an integer directly.
  • GetTickCount returns a DWORD, so use that for your tick count variables.


class FramesPerSecond
{
public:
FramesPerSecond();

void frameDone();

int getFPS() {
return m_fps;
}

private:
int m_fps, m_frameCount;
DWORD m_lastTime;
};

FramePerSecond::FramePerSecond()
: m_fps(0), m_frameCount(0), m_lastTime(0)
{
}

void FramePerSecond::frameDone()
{
++m_frameCount;

DWORD now = GetTickCount();

if(now - m_lastTime >= 1000)
{
m_lastTime = now;

m_fps = m_frameCount;
m_frameCount = 0;
}
}





Bigger picture:

Consider using a different performance metric than FPS altogether. Using frame times directly provides a better metric when comparing how performance has changed due to code changes, etc. See here. Also see this post by frob for how minimum and maximum values for frame times can help provide a clearer picture into what's going on.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this