Is this a valid FPS calculation?

Since FPS is so important, I want to make sure I didn’t make some sort of typical newbie programmer mistake here. If so, please straighten me out.

private void displayFrameRate(GL gl)
{
// num frames since last update
frameCount++;

// time passed since last update 
timeDelta = System.currentTimeMillis() - oldTime;

// if it's been longer than a quarter second, update    
if(timeDelta >= 250)                             
{    
    // calculate current fps                                      
    fps = (frameCount * 1000.0f) / timeDelta;   
  
    // oldTime becomes the current time
    oldTime = System.currentTimeMillis();         

    // reset frame count                              
    frameCount = 0; 

    //...                               
}

}

Thanks :slight_smile:

On windows in <1.5 this might not give good results because of the timer resolution of System.currentTimeMillis() being poor on some systems.

Seems ok other than that tho,

Kev

kevglass

I have heard that 1.5 has a higher rez timer, but I am not familiar with how to use it. Could you recommend a modification to this code?

Thanks for the advice.

My suggested improvements:

  1. Use integer math to control the rounding errors better. (I use “timeDelta = timeDelta%msPerFpsSample” to let the “rounding error” spill over to the next iteration)

  2. Don’t sample the time twice. Sample it once (“long now = System.currentTimeMillis()”) and reuse the value.
    Sampling it twice means the time between the two System.currentTimeMillis() will go uncounted, resulting in an fps calculation that is slightly too fast.

  3. Don’t use System.currentTimeMillis. :wink:
    If you have to, set fpsSamplesPerSecond to a value as low as possible.

int fpsSamplesPerSecond = 4;
int msPerFpsSample = 1000/fpsSamplesPerSecond;
int frameCount;
int timeDelta;

private void displayFrameRate(GL gl) 
{ 
  frameCount++; 
 
  long now = System.currentTimeMillis();
  timeDelta += (int)(now - oldTime); 
  oldTime = now;
 
  if(timeDelta >= msPerFpsSample)
  {
    int passedSamples = timeDelta/msPerFpsSample;
    fps = frameCount * fpsSamplesPerSecond / passedSamples;
    timeDelta = timeDelta%msPerFpsSample;
    frameCount = 0;  
  } 
}

[edit: Oops.]

[edit again: Made it handle when timeDelta > msPerFpsSample*2]

Markus,

Your version is clearly superior to mine, so I will happily incorporate it into the base code I am slowly getting together for my learning projects.

I had a question about this: it seems you are suggesting I might remove the need for the call to System.currentTimeMillis() by altering the value of fpsSamplesPerSecond, and, if so, I don’t understand how to do it and why it would work.

Thanks :slight_smile:

The high resolution timer in 1.5 is called with System.nanoTime().

What’s the granularity on Windows XP?

It should be the same as Win2k, so in the range of 10ms.

Edit: stupid me. 10ms is the resolution of System.getTime on XP. An actual hi res timer on XP is rather accurate (down to clock ticks if I remember right).

So, until Uncle Bill improves his OS, will there be any advantage to using nanoTime?

[quote]I had a question about this: it seems you are suggesting I might remove the need for the call to System.currentTimeMillis() by altering the value of fpsSamplesPerSecond, and, if so, I don’t understand how to do it and why it would work.

Thanks :slight_smile:
[/quote]
No, you’re always going to have to call some kind of timer. =)
I just meant that if you’re stuck with the only one included in standard java 1.4 (ie System.currentTimeMillis()), you have to keep in mind it’s fairly inaccurate at high sample rates.

Well, that’s a relief…I thought you people must REALLY be gods if you had some trickery to get around calling the timer :slight_smile:

[quote]So, until Uncle Bill improves his OS, will there be any advantage to using nanoTime?
[/quote]
Well, on win9x it’s even worse. 50-55msec.

The advantage you ask? It’s precision :slight_smile:

The usual (old) timers aren’t even good enough for measuring network latency. They are good for nothing. Whereas a nano timer can give you a very precise idea of how much time actually passed. You can use it for frame capping or accurate time based movement without using all those ugly hacks.

So if you can use a nano timer - use it.

Ok, I saw Orangy Tang’s edit to his post, and the timer deal makes sense now.

I just implemented the nano timer for use in elapsed-time based adjustments to player position etc. and it was certainly a night and day change in performance.

Thanks for the tip.

What would be the disadvantages of integrating the Gage timer (other than a slightly increased total application size)?

We use the GAGE timer in wurm so we’ll get good timing in java 1.4.
Haven’t noticed any disadvantages.

Oh, well, actually, since it’s native code, you’ll need to sign your application. By using the 1.5 timer, you could make a “safe” game that doesn’t require signing.

Well, jogl is also an evil native thingy. So he has to sign it anyways ::slight_smile:

evil. ha ha ha</evil laugh>

I don’t want to have to focus my clients to use 1.5 (which isn’t officially out yet - when will it be?), so i’ll look into implementing the Gage timer tomorrow which should take all of 3 minutes if that to integrate. :smiley:

[quote]Well, jogl is also an evil native thingy. So he has to sign it anyways ::slight_smile:
[/quote]
I was just listing disadvantages of using gage timer. :wink:
If you’re already signing your app, that disadvantage is fairly small.

ok then, so it’s good news all round! I’ll implement Gage tomorrow - easy to implement, nice compliant high res timer, low footprint = good good good!

I found the following interesting discussion on Gage timer implementation with OSX:

http://forum.java.sun.com/thread.jsp?forum=406&thread=511289&tstart=120&trange=15