Alternatives for Sys.getTime() and Sys.getTimerResolution()? - java

In my client (using LWJGL), I use the following code:
private static long getTime() {
return (Sys.getTime() * 1000) / Sys.getTimerResolution();
}
However, I have also just finished coding a server for this game, and up until now, I am been using LWJGL only for the purpose of having that method in my code. Which really, is a bit impractical.
What is a suitable alternative for the above code that uses no libraries at all?

I think you might be looking for System.nanoTime() in the Java libraries. This method would obviously give you a long of the time, of which you could standardize into ticks.
// beginning of the game loop
long startTime = System.nanoTime();
// end of the game loop
long estimatedTime = System.nanoTime() - startTime;
You could divide this number by the amount of ticks you want per second (as Sys.getTimerResolution() does) and then you could have very similar operation to what the LWJGL library provides you.

Related

Start event upon a given timespan

I have been researching and I am struggling to actually choose the best option. I am using processing sketch that runs java code, and I want to start an animation in several computers( OS X and windows) at the same time. The basic idea is to send a OSC message to each computer and after they receive a message they will store the currentTime plus the timespan(let say after 10 second). And each computer track the currentTime and when it reach the intended Time they will start the animation. Now I cannot figure out which System should I use. System.currentTimeMillis() or System.nanoTime(); I already tested with two computers(both Systems) and it seems to work. Both computers are OS X but I never tried with a windows one and it seems for System.currentTimeMillis() can be a lag of 50ms. I'm really confuse in this matter. Someone can me explain or highlight.
thank in advance
Simultanous simulations on two or more computers is tricky for some reasons.
First of all I would make sure, all connected computers synchronize their clocks with NTP. (See more https://en.wikipedia.org/wiki/Network_Time_Protocol)
Then the biggest difference is at most 50ms as far as I know.
Otherwise every approach will fail because of the differences of the clocks.
Second, clocks on different systems have different accuracy. I can recommend reading Alexey Shipilev's blog: https://shipilev.net/blog/2014/nanotrusting-nanotime/ . It is about the accuracy of clocks on machines in general.
Third you need to know that Linux has a round robin slide of 1ms and Windows about 10-15ms. Therefore Thread.sleep(...) will not work with smaller time spans reliable.
If you want to´work with smaller time spans you need to do a kind of "busy waiting" which is ugly but necessary:
public class SleepUtil {
public static final long MIN_PRECISION_IN_MICROS = 15L;
public static void main(String[] args) {
long before = System.nanoTime();
while (true) {
final long after = System.nanoTime();
long diff = (after - before) / 1000l;
before = after;
System.out.println(diff + " micros");
SleepUtil.sleepMicros(500);
}
}
private static void sleepMicros(int waitTimeInMicros) {
final long startTimeInNanos = System.nanoTime();
long elapsedTimeInMicros = 0L;
while (elapsedTimeInMicros < waitTimeInMicros - MIN_PRECISION_IN_MICROS) {
elapsedTimeInMicros = (System.nanoTime() - startTimeInNanos) / 1000L;
}
}
}
However, it will busy your cpu and not be always reliable (but most of the time).

java code not working for while loop

i am trying to execute a code for 5 minutes within while loop.
long init= System.currentTimeMillis();
while(((System.currentTimeMillis()-time)/1000%60)<5){
//some part of code
}
but i am not able to get it working any suggestions how to fix it.
System.currentTimeMillis() depends on the implementation and on the Operating system.
Instead use the System.nanoTime() which returns the current value of the most precise available system timer, in nanoseconds.
That might be causing you time problems .
long init= System.nanoTime();
while(((System.nanoTime()-init)/1000000000/60)<5){
//some part of code
}
Just: Change the code as below and try again:
while(((System.currentTimeMillis()-time)/1000%60)<5){
To
while(((System.currentTimeMillis()-init)/1000/60)<5){
change time to init and % to /

Java: Why is calling a method for the first time slower?

Recently, I was writing a plugin using Java and found that retrieving an element(using get()) from a HashMap for the first time is very slow. Originally, I wanted to ask a question on that and found this (No answers though). With further experiments, however, I notice that this phenomenon happens on ArrayList and then all the methods.
Here is the code:
public class Test {
public static void main(String[] args) {
long startTime, stopTime;
// Method 1
System.out.println("Test 1:");
for (int i = 0; i < 20; ++i) {
startTime = System.nanoTime();
testMethod1();
stopTime = System.nanoTime();
System.out.println((stopTime - startTime) + "ns");
}
// Method 2
System.out.println("Test 2:");
for (int i = 0; i < 20; ++i) {
startTime = System.nanoTime();
testMethod2();
stopTime = System.nanoTime();
System.out.println((stopTime - startTime) + "ns");
}
}
public static void testMethod1() {
// Do nothing
}
public static void testMethod2() {
// Do nothing
}
}
Snippet: Test Snippet
The output would be like this:
Test 1:
2485ns
505ns
453ns
603ns
362ns
414ns
424ns
488ns
325ns
426ns
618ns
794ns
389ns
686ns
464ns
375ns
354ns
442ns
404ns
450ns
Test 2:
3248ns
700ns
538ns
531ns
351ns
444ns
321ns
424ns
523ns
488ns
487ns
491ns
551ns
497ns
480ns
465ns
477ns
453ns
727ns
504ns
I ran the code for a few times and the results are about the same. The first call would be even longer(>8000 ns) on my computer(Windows 8.1, Oracle Java 8u25).
Apparently, the first calls is usually slower than the following calls(Some calls may be longer in random cases).
Update:
I tried to learn some JMH, and write a test program
Code w/ sample output: Code
I don't know whether it's a proper benchmark(If the program has some problems, tell me), but I found that the first warm-up iterations spend more time(I use two warm-up iterations in case the warm-ups affect the results). And I think that the first warm-up should be the first call and is slower. So this phenomenon exists, if the test is proper.
So why does it happen?
You're calling System.nanoTime() inside a loop. Those calls are not free, so in addition to the time taken for an empty method you're actually measuring the time it takes to exit from nanotime call #1 and to enter nanotime call #2.
To make things worse, you're doing that on windows where nanotime performs worse compared to other platforms.
Regarding JMH: I don't think it's much help in this situation. It's designed to measure by averaging many iterations, to avoid dead code elimination, account for JIT warmup, avoid ordering dependence, ... and afaik it simply uses nanotime under the hood too.
Its design goals pretty much aim for the opposite of what you're trying to measure.
You are measuring something. But that something might be several cache misses, nanotime call overhead, some JVM internals (class loading? some kind of lazy initialization in the interpreter?), ... probably a combination thereof.
The point is that your measurement can't really be taken at face value. Even if there is a certain cost for calling a method for the first time, the time you're measuring only provides an upper bound for that.
This kind of behaviour is often caused by the compiler or RE. It starts to optimize the execution after the first iteration. Additionally class loading can have an effect (I guess this is not the case in your example code as all classes are loaded in the first loop latest).
See this thread for a similar problem.
Please keep in mind this kind of behaviour is often dependent on the environment/OS it's running on.

Measure the CPU time elapsed for a part of code in JAVA

I'm currently trying to measure the real elapsed cpu time for a part of my code in java.
I read that to get the CPU time you have to use the
cpuTime = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
but in fact when I try to measure it in that piece of code, an error is thrown when the elapsed time is equal to zero..... (which it appears to me to be impossible with a nano-sec precision). The while loop can be big or can also very small (aout 10 instuctions min).
long startTime = ManagementFactory.getThreadMXBean()
.getCurrentThreadCpuTime();
// reset with seed solution for each neighborRule and
// each pivoting rule
t.setCurrentBestSolution(seedSolution);
while (t.chooseNextImprovingNeighborSolution(pivotingRule,
neighborRule));
long endTime = ManagementFactory.getThreadMXBean()
.getCurrentThreadCpuTime();
if (endTime - startTime == 0) {
System.err.println(pivotingRule + ":" + neighborRule);
System.err.println("END TIME:" + endTime);
System.err.println("START TIME:" + startTime);
}
Any idea ? Am I not using properly the CPUThread part ?
Should I use an external java benchmarker ?
Thanks in advance
Should I use an external java benchmarker ?
Yes please do. Jprofiler measures the real elapsed time among other useful metrics.
The methods of System and Runtime class will help you.
Take a look on:
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Runtime.html
For example: You can use: System.currentTimeMillis(); which returns the time in millisecond, before and after your program! (at the beginning or end of main method!)

How to find elapsed time/benchmark a Java method/code using Eclipse?

I am trying to find a clean way to find elapsed time. In other words, I want to find the time it takes for a given section of code to get executed.
I know the following two approaches:-
1>
long start = System.nanoTime();
// Code to measure
long elapsedTime = System.nanoTime() - start;
2>
long start = System.currentTimeMillis();
// Code to measure
long elapsedTime = System.currentTimeMillis() - start;
But these two approaches are dirty in the sense I have to litter the original code with my benchmarking code and later when benchmarking is over I will have to remember to remove the code.
I am looking for a cleaner approach which is supported by Eclipse/any other IDE in which I mark the code that I want to benchmark just like we specify breakpoints and Eclipse shows me the elapsed time whenever that portion of code is reached.
Is there any such method available in Eclipse/any other IDE?
I recommend Perf4j perf4j.codehaus.org
Set a field at the top of your class
private static final boolean DEBUG_THIS=true;
then when you have lines you want to use, put them in like this:
if (DEBUG_THIS){
Log.v("Tag","It took " + System.currentTimeMillis() - start + " ms");
// perhpas some other debug code
}
Then when you are tired or done debugging, change the one line of code at the top
private static final boolean DEBUG_THIS=false;
you can leave all your debug code otherwise in place, there if you ever need it again, and costing you nothing in the running version.
You can write a JUnit Test for the code. The JUnit plug-in for Eclipse will show you the time it took to run the test.

Categories