Precise timer compatible Java 1.1

Hi, this is a try to do a more precise timer than System.currentTimeMillis

public class Timer implements Runnable
{
	private long lastTime;
	private long newTime;
	private long lastDiff;
	private long lastCount;
	private long count;
	private boolean run;
	private Thread process;
	
	public Timer()
	{
		this.lastCount=1;
		this.count=0;
		this.lastTime=System.currentTimeMillis();
		this.newTime=System.currentTimeMillis();
		this.process=new Thread(this);
		this.process.start();
		this.process.setPriority(Thread.MAX_PRIORITY);
	}
	
	public void start()
	{
	}
	
	public long getTime()
	{
		if(this.lastCount==0)
			return 0;
				
		long predicted=this.lastTime-this.lastDiff+this.count*this.lastDiff/this.lastCount;
		
		if(predicted<this.newTime)		
			return predicted;
		return this.newTime;
	}
	
	public void run()
	{		
		while(true)
		{
			this.setClock();
			try
			{
				Thread.sleep(1);	
			}
			catch(InterruptedException ie)
			{
				return;
			}
		}
	}
	
	private void setClock()
	{
		this.newTime=System.currentTimeMillis();			
		
		if(this.newTime>this.lastTime)
		{
			this.lastCount=this.count;
			this.count=1;
			this.lastDiff=this.newTime-this.lastTime;
			this.lastTime=this.newTime;
		}
		else			
		{
			this.count++;
		}			
	}
}

here a code to test

		this.t=new Timer();

		int nbLoop=100;
		
		long systemTimes[]=new long[nbLoop];
		long timerTimes[]=new long[nbLoop];
		long diffTimes[]=new long[nbLoop];
		
		long systemTime=System.currentTimeMillis();
		long timerTime=t.getTime();
		
		for(int n=0;n<nbLoop;n++)
		{
			
			try
			{
				Thread.sleep(1); //Replace that to try different interval
			}
			catch(InterruptedException ie)
			{
				
			}

			long newSystemTime=System.currentTimeMillis();
			long newTimerTime=t.getTime();
			systemTimes[n]=newSystemTime-systemTime;
			timerTimes[n]=newTimerTime-timerTime;
			diffTimes[n]=newSystemTime-newTimerTime;
			
			//timerTime=newTimerTime;			
			//systemTime=newSystemTime;
		}

		System.out.println("systemTimes[n]\t\ttimerTimes[n]\t\tdiffTimes[n]");
		for(int n=0;n<nbLoop;n++)
		{
			System.out.println(systemTimes[n]+"\t\t"+timerTimes[n]+"\t\t"+diffTimes[n]);				
		}	

Hello.
Nice one !
I first didn’t think this would work, as sleep() ought to have the same granularity as currentTimeMillis() -or so i believed-.
Maybe there is a special case with (1)?

Did you make any profiling in a real app ?

no, I did not really try it on real app, but I guess it wil have some trouble if CPU is used 100% for too long

[quote]Maybe there is a special case with (1)?
[/quote]
the sleep(1) in the run method could be replaced by any other instruction that do not use much cpu and time , I use sleep because it is the only instruction matching those requierment

a runnable timer? Why? What’s in it that you can’t get with 3-4 lines of code using System.nanoTime()?

btw. I think sleep(1) is low res and could sleep 1-20 ms actually on windows. Windows has timer resolution of 20 ms I think and sleep uses it. Maybe I’m wrong, I remember this from Killer Game Programming in Java.

nanotime doesnt exist in java 1.1

as I explain above sleep(1) can be replaced by any other instruction that use not much cpu and time, please look more closer to see how this timer works, it compute an average tick between two different time of currentmillis

previous -> next
old -> new
first -> last

You have abit of a mix-up in your naming :wink:

The resolution of currentTimeMillis is 50-55 msec on win9x, 10msec on 2k/xp and 1msec on linux/mac.

On win9x you can surely sleep less than 50-55msec (down to about 5msec iirc), but usually it will be pretty jumpy, because there is absolutely no guarantee that sleep will actually return the control at the desired time.

The idea to use a seperate sleep thread isnt new btw. Someone (from here I think) experimented with that a few years ago. Well, I personally prefer my adaptive yield loop thingy, which is just fine for most kind of games (if you’re fine with the tickbased route) and it even works pretty well if the timer resolution is as bad as 250msec.

Trying to make a general purpose timer somehow misses the point a bit imo. If you only want to use it for games (or similar things) you can do things a bit differently. If its used in a render loop the time is requested once per frame and the delta from one frame to the next will be always pretty similar (compared to the previous one) for the most part.

That means that you can use things like rolling average, inter-/extrapolating and damping for getting a pretty accurate delta.

For example if the last 5 frames took 10msec each (on average) and the calculated delta determined with currentTimeMillis is 0, then the real delta is actually most likely pretty close to 10msec instead of 0.

I began this thread with that sentence

[quote]…this is a try to do a more precise timer …
[/quote]
and so, I never said that this timer should be used for general purpose but in some case it will help to get a better timer on 1.1 platform target.

[quote]The idea to use a seperate sleep thread isnt new btw. Someone (from here I think) experimented with that a few years ago.
[/quote]
what this timer do is a bit more complex than : while(Thread.sleep(1)) time++ :wink:
as I explain above you can replace the Thread.sleep(1) by Thread.yield() it will works the same even with a system timer resolution as bad as 250ms

EDIT: this timer works like an FPS counter (reversed of course)

[quote]Well, I personally prefer my adaptive yield loop thingy, which is just fine for most kind of games (if you’re fine with the tickbased route) and it even works pretty well if the timer resolution is as bad as 250msec.
[/quote]
it can also be used in a main loop without the need to start the thread by calling: setClock() in the main loop, i guess that it will works the same.

EDIT: if framerate is higher than the timer resolution