Time tracking in Java: using currentTimeMills() - java

I got an interesting "time-travel" problem today, using the following code:
for (int i = 0; i < 1; i++){
long start = System.currentTimeMillis();
// Some code here
System.out.print(i + "\t" + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
// Some code here
System.out.println("\t" + (System.currentTimeMillis() - start));
}
And I got the result
0 15 -606
And it seems that it is not repeatable. Anyone has any clues on what happened inside during the running time? Just curious...
New edit: I used a small test to confirmed the answers below. I run the program and change the system time during the run, and finally repeat the "time-travel":
0 -3563323 163
Case closed. Thanks guys!
More words: both currentTimeMillis() and nanoTime() are system-timer based, so they will be not monotonic if the system timer is updated (turned back, specifically). It is better to use some internet-based timer for such cases.

System.currentTimeMillis() depends on the system time. So it could be modified by third party systems.
For measuring time is System.nanoTime() the better option.

I recall something like time adjustments made to the systems time once in a while too match actual time. And since currentTimeMillis relies on the system clock that might have happened. Also are you synchronizing with a time server, that could also be.

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 - repeatedly run a function in a given number of milliseconds accurately?

Does anyone have a Fairly effective way of running a function repetitively in a precise and accurate number of milliseconds. I have tried to accomplish this by using the code below to try to run a function called wave() once a second for 30 seconds:
startTime = System.nanoTime();
wholeTime = System.nanoTime();
while (loop) {
if (startTime >= time2) {
startTime = System.nanoTime();
wave();
sec++;
}
if (sec == 30) {
loop = false;
endTime = System.nanoTime();
System.out.println(wholeTime - System.nanoTime());
}
}
}
This code did not work and am wondering why this code didn't work and if their is a better approach to the problem. Any ideas on how to improve fix the above code or other successful ways of accomplishing the problem are all welcome. Thank you for your help!
more simple:
long start=System.currentTimeMillis(); // Not very very accurate
while (System.currentTimeMillis()-start<30000)
{
wave();
// count something
}
You can use a Timer+TimerTask: https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html
https://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html
http://bioportal.weizmann.ac.il/course/prog2/tutorial/essential/threads/timer.html
You may use Thread.sleep():
public static void main (String[] args) throws InterruptedException {
int count = 30;
long start = System.currentTimeMillis();
for(int i=0; i<count; i++) {
wave();
// how many milliseconds till the end of the second?
long sleep = start+(i+1)*1000-System.currentTimeMillis();
if(sleep > 0) // condition might be false if wave() runs longer than second
Thread.sleep(sleep);
}
}
Does anyone have a Fairly effective way of running a function repetitively in a precise and accurate number of milliseconds.
There is no way to do this kind of thing reliably and accurately in standard Java. The problem is that there is no way that you can guarantee that your thread will run when you want ti to run. For example:
your thread could be suspended to allow the GC to run
your thread could be preempted to allow another thread in your application to run
your thread could be suspended by the OS while it fetches pages by the JVM back from disk.
You can only get reliable behavior for this kind of code if you run on a hard realtime OS, and an realtime Java.
Note that this is not an issue with clock accuracy. The real problem is that the scheduler does not give you the kind of guarantees you need. For instance, none of the "sleep until X" functionality in a JVM can guarantee that your thread will wake up at time X exactly ... for any useful meaning of "exactly".
The other answers suggest various ways to do this, but beware that they are not (and cannot be) reliable and accurate in all circumstances .. or even on a typical machine running other things as well as your application.

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