Java-Gaming.org Java4K winners: [ by our judges | by the community ]         
Featured games (67)
games approved by the League of Dukes
Games in Showcase (∞)
games submitted by our members



News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  Print  
  High Resolution Timer in Java 1.4.2  (Read 4430 times)
0 Members and 1 Guest are viewing this topic.
Offline aikarele

JGO n00b
*

Posts: 39



« on: 2003-05-17 01:38:39 »

There is a "hidden" high resolution timer in J2SE 1.4.2, here is an example timer class how to use it:

import sun.misc.Perf;

public class HiResTimer {
  Perf hiResTimer;
  long freq;

  public HiResTimer() {
     hiResTimer = Perf.getPerf();
     freq = hiResTimer.highResFrequency();
  }

  public long currentTimeMillis() {
     return hiResTimer.highResCounter() * 1000 / freq;
  }
}

and here is a little example program for measuring the accuracy of the class above:

public class TimerTest {
  public static void main(String[] args) {
     long start, stop;
     HiResTimer testTimer = new HiResTimer();
     start = testTimer.currentTimeMillis();
     while(testTimer.currentTimeMillis() == start);
     stop = testTimer.currentTimeMillis();
     System.out.println("Time: "+(stop-start)+" ms");
  }
}

With Windows XP I got 1 ms accuracy. With a similar test program I got 10 ms accuracy for System.currentTimeMillis(). At least with WinXP the "hidden" timer actually gives a much better accuracy than 1 ms, I guess it uses the same Windows timer as Java3D high resolution timer. The freq parameter with my WinXP setup is 3579545 ticks / second. I haven't tested it with other operating systems (Linux/Solaris/Win2000/Win98...). If someone is using any of those operating systems, please post the accuracy to this forum...
Offline oNyx

JGO Kernel
*****

Posts: 2943
Medals: 5


pixels! :x


« Reply #1 on: 2003-05-17 07:15:48 »

Hey aikarele Cheesy

I've seen your 64k demo (varhaiset_signaalit) several months ago and was really impressed. It was the first demo I've seen wich was written in Java and it was able to run in fullscreen Shocked (I hadn't known that it's possible before).

Without your demo I won't be here. Thank you for bringing me back to this wonderful language Smiley

Gonna update my VM in some hours. I'll drop the results (win98se) here.

弾幕 ☆ @mahonnaiseblog
Offline Themroc

Jr. Member
**

Posts: 70



« Reply #2 on: 2003-05-17 07:16:03 »

Hm ... not documented, may move or vanish with every new release. I hope the make it a public part of the API soon.

Edit: I tested it on some Linux/Athlon machine (don't ask me about details)
:~> j2sdk1.4.2/bin/java TimerTest
Time: 1 ms
Games published by our own members! Go get 'em!
Offline Orangy Tang

JGO Kernel
*****

Posts: 2960
Medals: 37


Monkey for a head


« Reply #3 on: 2003-05-17 07:31:19 »

Quote
several months ago and was really impressed. It was the first demo I've seen wich was written in Java and it was able to run in fullscreen Shocked (I hadn't known that it's possible before).


Not to knock the demo, but this was possibly in java about a year ago (albeit buggy in the first 1.4 VMs). There was lots of experimentation and apps using it from people on the forum.

Is this a new timer? I would have thought it would be easier to move across the high res timer from j3d. Maybe its just a different wrapper around the same native code..

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline oNyx

JGO Kernel
*****

Posts: 2943
Medals: 5


pixels! :x


« Reply #4 on: 2003-05-17 07:48:58 »

Quote


Not to knock the demo, but this was possibly in java about a year ago (albeit buggy in the first 1.4 VMs). There was lots of experimentation and apps using it from people on the forum.
[...]


Yes... I know that Tongue

I just had lost interest in Java ~2 years ago; therefore I wasn't aware of the api changes, hadn't checked any demo applications and didn't visit any Java forum. Simply because I wasn't interested.

Btw the demo (intro) was from assembly2002... so fullscreen was quite new to Java the days the demo was made.

弾幕 ☆ @mahonnaiseblog
Offline Smoke

JGO n00b
*

Posts: 28


games rock!


« Reply #5 on: 2003-05-17 08:14:14 »

Hi

first message on this board Smiley glad i can post something usefull:

Here's my Timing class (note the cast):

//------------------------------------------------------
import sun.misc.Perf;

public class PerfTimer {
     Perf hiResTimer;
     long freq;
     
     public PerfTimer() {
           hiResTimer = Perf.getPerf();
           freq = hiResTimer.highResFrequency();
     }
     
     public double getTime() {
           return (double)hiResTimer.highResCounter() * 1000 / (double)freq;
     }
}

//------------------------------------------------------


This is the Testing class:

//------------------------------------------------------
public class Test {
     public static void main(String[] args) {
           PerfTimer t = new PerfTimer();
           double start, end, delta, sumOfDeltas, averagedelta;
           int resTestIterations = 1000;
           
           System.out.println("Test1: measure a system-timed intervall");
           start = t.getTime();
           long sysstart = System.currentTimeMillis();
           long sysend;
           do { sysend = System.currentTimeMillis(); }
           while ( sysend < sysstart + 1000);
           end = t.getTime();
           long sysdelta = sysend-sysstart;
           delta = end-start;
           
           System.out.println("systimer-delta: "+sysdelta);
           System.out.println("perftimer-delta: "+delta);
           
           System.out.println("\nTest2: resolution");
           sumOfDeltas = 0;
           for (int i=0;i<resTestIterations;i++) {
                 start = t.getTime();
                 while (start == t.getTime());
                 end = t.getTime();
                 delta = end-start;
                 sumOfDeltas += delta;
           }
           averagedelta = sumOfDeltas/resTestIterations;
           System.out.println("resolution: "+ delta);
           System.out.println("average resolution:"+ averagedelta);
           
           
           System.out.println("\nTest3: measure a perf-timed intervall with sys-timer");
           sysstart = System.currentTimeMillis();
           start = t.getTime();
           do end = t.getTime();
           while (end <start+1000);
           sysend = System.currentTimeMillis();
           delta = end-start;
           sysdelta = sysend-sysstart;
           System.out.println("Perf-delta:"+delta);
           System.out.println("system-Time-delta:"+sysdelta);
     }
}
//------------------------------------------------------


its quite long but i couldn't believe the results first Smiley

this is an example output (using Win98se)

Test1: measure a system-timed intervall
systimer-delta: 1040
perftimer-delta: 1002.6182135134682

Test2: resolution
resolution: 0.011733351212569687
average resolution:0.013178229604925037

Test3: measure a perf-timed intervall with sys-timer
Perf-delta:1000.3126100001673
system-Time-delta:980

so this timer actually seems to have ~12E-6 second resolution (is that 12 nanos in english or 12mycro?)

the differences between perf and sys timing are always inside the 50ms-accuracy of the system-timer.

the average resolution goes up and down a bit betweend differnt tests but usually just around 0.002 millis.

lets hope sun has a heart for gamers and leaves this timer!
Offline aikarele

JGO n00b
*

Posts: 39



« Reply #6 on: 2003-05-17 12:00:36 »

oNyx, thanks for your nice feedback. We are going to release even better Java stuff this year, so stay tuned  Wink

Themroc, yes it could vanish any time. But Florian Bomers (the guy responsible for Java Sound at Sun) is going to use it in Tritonus' Java sequencer, so I guess at least he is not expecting it to vanish soon. I guess they could not make it an "official" timer class in J2SE 1.4.2, because it would have been a new feature, but I hope it will be an official class in J2SE 1.5.

Orangy Tang, our demo (actually a 64 kB intro) was released almost a year ago, and we made it using J2SE 1.4.0 beta. So although it was not made to demonstrate fullscreen API, it definitely was made with the first possible Java SDK that had fullscreen API support  Wink. And to my great surprise, it actually works BETTER with 1.4.0 than 1.4.1 or 1.4.2. About the timers; my guess is that both the Windows implementation of the "new" timer and J3D timer (and several native timers floating in the web) use QueryPerformanceCounter and QueryPerformanceFrequency functions.

Smoke, you can actually get the resolution of the timer with hiResTimer.highResFrequency() method  Wink. Resolution on my WinXP set up is 3579545 ticks/sec, which means a resolution of 1/3579545 = 0.000000279365114840015 s.

Those of you who wonder what is varhaiset signaalit, you can download it from here:
http://www.pouet.net/prod.php?which=7145
Offline Kommi

Sr. Member
**

Posts: 293


All opinions will be lined up and shot!


« Reply #7 on: 2003-05-21 14:12:01 »

Hey how did you save you images for the demo?

Kommi
Offline aikarele

JGO n00b
*

Posts: 39



« Reply #8 on: 2003-05-22 10:33:20 »

Read the introFAQ.txt  Wink. We developed image compression algorithms that allowed us to save the images in 640x480 resolution using about 1.5 kB per image.
Offline Mark Thornton

Sr. Member
**

Posts: 473
Medals: 2



« Reply #9 on: 2003-05-28 02:24:53 »

Using a slight different test on my 3.06GHz XP machine I obtained the following

HiRes counter frequency: 3.0496E9
Mean counter call: 628.34E-9s

On dual processor machines the Windows QueryPerformanceCounter api uses the processor clock counter. This could lead to unexpected results when the processor slows down due to overheating.



import sun.misc.Perf;
import java.text.DecimalFormat;

class TestPerformance
{
     public static void main(String[] args)
     {
           Perf p = Perf.getPerf();
           long freq = p.highResFrequency();
           DecimalFormat engFormat = new DecimalFormat("##0.##E0");
           System.out.println("HiRes counter frequency: "+engFormat.format(freq));
           System.out.println("Performance class: "+p.getClass());
           
           for (int i=1; i<20; i++)
           {
                 int n=500;
                 long t=0;
                 for (int j=0; j<n; j++)
                 {
                       long t0=p.highResCounter();
                       t += p.highResCounter()-t0;
                 }
                 System.out.println("Mean counter call: "+engFormat.format(t/(n*(float)freq))+"s");
           }
     }
}

Games published by our own members! Go get 'em!
Offline lilspikey

JGO n00b
*

Posts: 27


Computers Stole My Social Skills


« Reply #10 on: 2003-06-07 04:34:56 »

If you are worried about those classes disappearing/moving you coudl dynamically load them.  If they aren't available default to System.currentTimeMillis().

e.g.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
public interface Timer {
    public long currentTimeMillis();
}

public class HiResTimer implements Timer {
    Perf hiResTimer;
    long freq;
 
    public HiResTimer() {
        hiResTimer = Perf.getPerf();
        freq = hiResTimer.highResFrequency();
    }
 
    public long currentTimeMillis() {
        return hiResTimer.highResCounter() * 1000 / freq;
    }

}

public class StdTimer implements Timer {
    public long currentTimeMillis() {
        return System.currentTimeMillis();
    }
}


Then when making a timer:

1  
2  
3  
4  
5  
6  
7  
8  
9  
Timer timer = null;
try {
    Class timerClass = Class.forName( "HiResTimer" );
    timer = (Timer)timerClass.newInstance();
}
catch( Throwable t ) {
    // if we fail to make a hi-res timer
   timer = new StdTimer();
}


Offline aikarele

JGO n00b
*

Posts: 39



« Reply #11 on: 2003-06-07 13:08:01 »

Yep, if you use the hires timer, you definitely need a fallback in case it is not available. But I think it would be nicer if the availability of the hires timer is checked by the Timer class itself, not the caller. For example, the code could be something like this:

Quote

import sun.misc.Perf;

public class Timer {
   Perf hiResTimer;  
   long freq;  
     boolean hires = false;

   public Timer() {
           try {
              hiResTimer = Perf.getPerf();
                 freq = hiResTimer.highResFrequency();
              hires = true;
           }
           catch(Throwable t) { }
     }

   public long currentTimeMillis() {
           if(hires == true) {
                 return hiResTimer.highResCounter() * 1000 / freq;
           }
           else {
                 return System.currentTimeMillis();
           }
   }
}


Then the caller could use the Timer like this:
1  
2  
   Timer timer = new Timer();
   long time = timer.currentTimeMillis();

Offline lilspikey

JGO n00b
*

Posts: 27


Computers Stole My Social Skills


« Reply #12 on: 2003-06-08 09:42:55 »

However that makes compilation more tricky.

Offline aikarele

JGO n00b
*

Posts: 39



« Reply #13 on: 2003-06-08 11:53:45 »

Tricky? Because you need a Java version that supports hires timer (i.e.  J2SE 1.4.2 at the moment) to compile it? Why on earth would you have hires fallback timer if you are not using such a compiler?  Wink

Besides, your code will not compile with any Java version because "import sun.misc.Perf;" is missing  Grin

[edit: sorry, of course your code will compile without the import unless the hires timer is needed]
Offline lilspikey

JGO n00b
*

Posts: 27


Computers Stole My Social Skills


« Reply #14 on: 2003-06-18 13:34:00 »

Sorry, I would have explained more, but I had visitors arrive, then the forum moved (and the PC I am using for the net has been misbehaving badly).

Yep.  That's what I meant, you can simply ignore/delete the HiResTimer class if it won't compile, rather than having to wade in and alter source code.

p.s. I think that this kind of thing is one of the coolest features of java.  It lets you dynamically exploit whatever features are available on the host, but still function on other systems with those features missing.  Shame it's a bit fiddly.  It would be really good if the reflection/introspection stuff was somehow more "builtin" mkaing it easier to use.  But then I guess it'd make it easier to abuse too Wink

Offline Jeff

JGO Kernel
*****

Posts: 3535


Got any cats?


« Reply #15 on: 2003-06-24 17:21:40 »

I believe this functionality is committed for 1.5
I suspect this is an early version to get the bugs out.

If its released as part of the 1.5 fromal release it will have a real (not Sun specific) package name.

JK

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline aikarele

JGO n00b
*

Posts: 39



« Reply #16 on: 2003-08-11 09:17:04 »

Quote
I've seen your 64k demo (varhaiset_signaalit) several months ago and was really impressed. It was the first demo I've seen wich was written in Java and it was able to run in fullscreen  (I hadn't known that it's possible before).

Without your demo I won't be here. Thank you for bringing me back to this wonderful language  


Well now we have released another 64 kB intro at Assembly 2003 called raskasmetallia, which uses the high resolution timer in Java 1.4.2  Wink

Feel free to download it from:
http://www.pouet.net/prod.php?which=10585

Comments, feedback and especially bug reports are all welcome...
Pages: [1]
  Print  
 
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.136 seconds with 20 queries.