# High resolution Timer class (especially Windows)

**URL:** <https://forum.juce.com/t/high-resolution-timer-class-especially-windows/2966>\
**Category:** Windows\
**Created:** [June 20, 2008, 3:40pm UTC](https://forum.juce.com/t/high-resolution-timer-class-especially-windows/2966 "2008-06-20T15:40:30Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![andreas](https://avatars.discourse-cdn.com/v4/letter/a/ee7513/32.png) [@andreas](https://forum.juce.com/u/andreas)\
**Post date:** [June 20, 2008, 3:40pm UTC](https://forum.juce.com/t/high-resolution-timer-class-especially-windows/2966/1 "2008-06-20T15:40:30Z")

</div>

The implementation of the Timer class uses “Time::getMillisecondCounter()”. This counter is in windows a very low resolution timer (about 16 milliseconds). In some applications I need timed events with a better resolution (near 10 or 12 millseconds), that are exactly timed.

Would it be possible to have another Timer class (or an option to the Timer class), that uses the high resolution “Time::getMillisecondCounterHiRes()”?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [June 20, 2008, 5:08pm UTC](https://forum.juce.com/t/high-resolution-timer-class-especially-windows/2966/2 "2008-06-20T17:08:42Z")

</div>

Well, no, there’d be no point - the Timer class uses event-based callbacks, so it’s inherently inaccurate.

But I’m not sure where you’re getting your information from - in my experience, the millisecond counter works very well, getting an accuracy of about 1ms.

---

<div class="post-metadata">

**Author:** ![andreas](https://avatars.discourse-cdn.com/v4/letter/a/ee7513/32.png) [@andreas](https://forum.juce.com/u/andreas)\
**Post date:** [June 23, 2008, 1:03pm UTC](https://forum.juce.com/t/high-resolution-timer-class-especially-windows/2966/3 "2008-06-23T13:03:23Z")

</div>

Using this test class for the timer functionality:

```auto
class TimerTest: public Timer
{
public:
	TimerTest(int milliSeconds):
		lastCounterHiRes(0)
	{
		printf("TimerTest: milliseconds = %d\n", milliSeconds);
		startTimer(milliSeconds);
	}
	~TimerTest()
	{
		stopTimer();
	}

	void timerCallback()
	{
		int64 counterHiRes = (int64)Time::getMillisecondCounterHiRes();
		printf("counter = %lld, difference = %lld\n", counterHiRes, counterHiRes-lastCounterHiRes);
		lastCounterHiRes = counterHiRes;
	}

private:
	int64 lastCounterHiRes;
};
```

I get the following output when testing on Windows XP SP2 on a HP xw4300 workstation for variuos values of milliseconds:

> [@](#):
>
> TimerTest: milliseconds = 9  
> counter = 21175592, difference = 21175592  
> counter = 21175599, difference = 7  
> counter = 21175616, difference = 17  
> counter = 21175631, difference = 15  
> counter = 21175647, difference = 16  
> counter = 21175662, difference = 15  
> counter = 21175677, difference = 15  
> counter = 21175694, difference = 17  
> counter = 21175709, difference = 15  
> counter = 21175724, difference = 15  
> counter = 21175741, difference = 17  
> …
> 
> TimerTest: milliseconds = 18  
> counter = 21169225, difference = 21169225  
> counter = 21169257, difference = 32  
> counter = 21169287, difference = 30  
> counter = 21169318, difference = 31  
> counter = 21169350, difference = 32  
> counter = 21169380, difference = 30  
> counter = 21169413, difference = 33  
> counter = 21169442, difference = 29  
> counter = 21169474, difference = 32  
> counter = 21169507, difference = 33  
> …
> 
> TimerTest: milliseconds = 27  
> counter = 21163478, difference = 21163478  
> counter = 21163506, difference = 28  
> counter = 21163536, difference = 30  
> counter = 21163568, difference = 32  
> counter = 21163600, difference = 32  
> counter = 21163630, difference = 30  
> counter = 21163663, difference = 33  
> counter = 21163692, difference = 29  
> counter = 21163724, difference = 32  
> …

Testing the same with Linux on the same workstation gives:

> [@](#):
>
> TimerTest: milliseconds = 9  
> counter = 1214223675567, difference = 1214223675567  
> counter = 1214223675579, difference = 12  
> counter = 1214223675587, difference = 8  
> counter = 1214223675596, difference = 9  
> counter = 1214223675605, difference = 9  
> counter = 1214223675614, difference = 9  
> counter = 1214223675623, difference = 9  
> counter = 1214223675633, difference = 10  
> …
> 
> TimerTest: milliseconds = 18  
> counter = 1214223687651, difference = 1214223687651  
> counter = 1214223687668, difference = 17  
> counter = 1214223687686, difference = 18  
> counter = 1214223687704, difference = 18  
> counter = 1214223687722, difference = 18  
> counter = 1214223687740, difference = 18  
> counter = 1214223687758, difference = 18  
> counter = 1214223687776, difference = 18  
> counter = 1214223687794, difference = 18  
> …
> 
> TimerTest: milliseconds = 27  
> counter = 1214223701022, difference = 1214223701022  
> counter = 1214223701049, difference = 27  
> counter = 1214223701076, difference = 27  
> counter = 1214223701103, difference = 27  
> counter = 1214223701130, difference = 27  
> counter = 1214223701158, difference = 28  
> counter = 1214223701185, difference = 27  
> counter = 1214223701212, difference = 27  
> counter = 1214223701239, difference = 27  
> counter = 1214223701266, difference = 27

Which is not 100% perfect, but much more accurate and as precise as I need it.

For testing I changed the implementation of “InternalTimerThread::run” to use “Time::getMillisecondCounterHiRes()” instead of “Time::getMillisecondCounter()” and that gives the following results on windows

> [@](#):
>
> TimerTest: milliseconds = 9  
> counter = 21039624, difference = 21039624  
> counter = 21039625, difference = 1  
> counter = 21039635, difference = 10  
> counter = 21039645, difference = 10  
> counter = 21039654, difference = 9  
> counter = 21039664, difference = 10  
> counter = 21039674, difference = 10  
> counter = 21039684, difference = 10  
> counter = 21039693, difference = 9  
> …  
> TimerTest: milliseconds = 18  
> counter = 21033361, difference = 21033361  
> counter = 21033379, difference = 18  
> counter = 21033397, difference = 18  
> counter = 21033416, difference = 19  
> counter = 21033435, difference = 19  
> counter = 21033452, difference = 17  
> counter = 21033471, difference = 19  
> counter = 21033489, difference = 18  
> counter = 21033508, difference = 19  
> …  
> TimerTest: milliseconds = 27  
> counter = 21027819, difference = 21027819  
> counter = 21027847, difference = 28  
> counter = 21027873, difference = 26  
> counter = 21027900, difference = 27  
> counter = 21027928, difference = 28  
> counter = 21027956, difference = 28  
> counter = 21027983, difference = 27  
> counter = 21028011, difference = 28  
> counter = 21028039, difference = 28

Also not perfect, but within the accurateness I need.

To my opinion this is because “Time::getMillisecondCounter()” is based on the Windows function “GetTickCount” and that is this inaccurate.

---

<div class="post-metadata">

**Author:** ![andreas](https://avatars.discourse-cdn.com/v4/letter/a/ee7513/32.png) [@andreas](https://forum.juce.com/u/andreas)\
**Post date:** [June 23, 2008, 1:56pm UTC](https://forum.juce.com/t/high-resolution-timer-class-especially-windows/2966/4 "2008-06-23T13:56:16Z")

</div>

Just an additional remark: When testing this, I found that obviously the “Time::getMillisecondCounterHiRes” on Linux returns the milliseconds since epoch and not since system startup as in Windows and as stated in the documentation.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [June 23, 2008, 6:05pm UTC](https://forum.juce.com/t/high-resolution-timer-class-especially-windows/2966/5 "2008-06-23T18:05:01Z")

</div>

…but like I said above, that test is completely meaningless, because the Timer class uses the event-loop. All the callbacks are completely at the mercy of other events, like repaints, button clicks, mouse-moves, other timers, etc, so they could be several _seconds_ late, not just milliseconds.

If you ran a loop that just printed the value of Time::getMilliseconds, you’d see that the resolution is actually very good. But the Timer class is absolutely not designed for time-critical events.

---

<div class="post-metadata">

**Author:** ![andreas](https://avatars.discourse-cdn.com/v4/letter/a/ee7513/32.png) [@andreas](https://forum.juce.com/u/andreas)\
**Post date:** [June 24, 2008, 10:09am UTC](https://forum.juce.com/t/high-resolution-timer-class-especially-windows/2966/6 "2008-06-24T10:09:47Z")

</div>

Do you really mean “Time::getMillisconds”? This method returns the milliseconds part of a Time object and it’s resolution depends how you initialised the Time object.  
I am talking of “Time::getMillisecondCounter” which is used internally by the Timer class.  
I created this very simple test program:

```auto
int main(int argc, char** argv)
{
	initialiseJuce_NonGUI();

	for (int i=0; i<100000; i++)
	{
		printf("Time::getMillisecondCounter(): %u\n", Time::getMillisecondCounter());
	}

	shutdownJuce_NonGUI();
	return 0;
}
```

The output on my windows machine is the following:

> [@](#):
>
> Time::getMillisecondCounter(): 12104187  
> Time::getMillisecondCounter(): 12104187  
> Time::getMillisecondCounter(): 12104187  
> Time::getMillisecondCounter(): 12104187  
> Time::getMillisecondCounter(): 12104187  
> Time::getMillisecondCounter(): 12104187  
> Time::getMillisecondCounter(): 12104187  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> …  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104203  
> Time::getMillisecondCounter(): 12104218  
> Time::getMillisecondCounter(): 12104218  
> Time::getMillisecondCounter(): 12104218  
> Time::getMillisecondCounter(): 12104218  
> Time::getMillisecondCounter(): 12104218  
> Time::getMillisecondCounter(): 12104218  
> Time::getMillisecondCounter(): 12104218  
> Time::getMillisecondCounter(): 12104218  
> Time::getMillisecondCounter(): 12104218  
> …

and so on. On Linux it really switches every millisecond.

I understand that the Timer class is not designed for time-critical events, but I do not understand that my test is completely meaningless, when it shows, that it could be much better in Windows, if “Time::getMillisecondCounter” is replaced with “Time::getMillisecondCounterHiRes” in the implementation of the Timer class.

The behaviour of the Timer class is sufficient for my applications on Linux and could be sufficient on Windows, if it would use the HiRes counter. But the default behaviour (at least on my test machines) on Windows is not good enough.

Do you have any other explanation, why “Time::getMillisecondCounter()” behaves in this way on my machines on Windows. Is there a mistake that I can make when building and linking Juce applications??

---

<div class="post-metadata">

**Author:** ![rbocquier](https://avatars.discourse-cdn.com/v4/letter/r/9fc348/32.png) [@rbocquier](https://forum.juce.com/u/rbocquier)\
**Post date:** [June 24, 2008, 2:18pm UTC](https://forum.juce.com/t/high-resolution-timer-class-especially-windows/2966/7 "2008-06-24T14:18:19Z")

</div>

Hi,

I tend to support Andreas.  
Another timing source with better accuracy on the Windows platform is the timeGetTime() function from the Multimedia API.  
You have a discussion about this very problem here, where Paul di Lascia comment about a remark I made :  
[http://msdn.microsoft.com/en-us/magazine/cc163931.aspx](http://msdn.microsoft.com/en-us/magazine/cc163931.aspx)

Robert

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [June 24, 2008, 4:39pm UTC](https://forum.juce.com/t/high-resolution-timer-class-especially-windows/2966/8 "2008-06-24T16:39:23Z")

</div>

Well, if you need a hi-res timer, use Time::getMillisecondCounterHiRes()… that’s why it’s there. And if you just need a plain old, not-too-fussy counter, use Time::getMillisecondCounter().

On a side-note, I used to use timeGetTime(), but changed it to GetTickCount(). Can’t actually remember why I changed that…
