Problem with System.nanoTime() - java

I´m working on a 2d java game but I´m stuck on timer problems. Here is my game loop:
void gameLoop(isRunning){
....
doStuff();
....
}
I have a fps measuring code like this inside the loop:
long thisLoop = System.currentTimeMillis();
delta = thisLoop - lastLoopTime;
lastLoopTime = thisLoop;
So I get how much time has passed since last loop. However, whenever I try to use System.nanoTime() instead of System,currentTimeMillis() like this:
long thisLoop = System.nanoTime();
delta = thisLoop - lastLoopTime;
lastLoopTime = thisLoop;
My game gets completely screwed, doesn't render anything past first frame, no errors reported just frozen. I´m on win 7 64 lastest java 1.6. What could be wrong?

Try using System.nanoTime() / 1000000 since it's in nanoseconds instead of milliseconds like you're probably expecting.

Are you multiplying or dividing by 1,000,000? 1 millisecond = 1 000 000 nanoseconds. I'm assuming that the rest of your logic is implemented in terms of milliseconds.

Related

How can I start a LIBGDX particle effect mid way through?

Is it possible to start a particle effect mid way through? I have tried many variations of updating the particle effect/emitters upon initialisation. None of them seem to work. Has anyone managed to do this before? Thanks a lot!
ParticleEffectPool.PooledEffect effect = particleEffectPool.obtain();
effect.setPosition(posnX,posnY);
float value = 1.5f;
for(ParticleEmitter e: effect.getEmitters()){
e.update(value);
value+=1.5f;
}
The above code doesn't draw all of the particles, but it does seem to update the them somewhat. Once the initial effect is over, it resets and then it looks fine
EDIT: I've found a little bit of a hack by doing the following code snippet 5 times upon initialisation of the particle effect. Still interested to see if someone has a better solution
p.getEmitters().get(0).addParticle();
p.update(1);
I assume, that all emitters in your ParticleEffect have the same duration:
ParticleEffectPool.PooledEffect effect = particleEffectPool.obtain();
effect.reset();
effect.setPosition(posnX,posnY);
//divide by 1000 to convert from ms to seconds
float effectDuration = effect.getEmitters().first().duration / 1000f;
float skipProgress = 0.5f;
effect.update(skipProgress * effectDuration);
Note, that if emitters have different duration, you probably would want to pick the max duration. Also, if your emitters have delays, you should take them into account too.
Update
This approach will not work as expected in case, when some of effect's properties change over time. So if you skip half of its duration, you don't take in account all changes that happened before. You just start from some state.
For example, let's say effect has duration = 10, and its velocity is 100 for the first 4 seconds, and after that velocity is 0. If you call effect.update(5), i.e. just skip first 5 seconds, particles will have velocity = 0, they just won't "know", that they had to move for the first 4 seconds.
So, I guess the only workaround here, is to update the effect with small steps in a loop, instead of just updating for half of its duration in one call:
ParticleEffectPool.PooledEffect effect = particleEffectPool.obtain();
effect.reset();
effect.setPosition(posnX,posnY);
//divide by 1000 to convert from ms to seconds
float skipDuration = 0.5f * effect.getEmitters().first().duration / 1000f;
//I guess, to reduce number of iterations in a loop, you can safely use
//a bit bigger stepDeltaTime, like 1 / 10f or bigger, but it depends on you effect;
//here I just use standard frame duration
final float stepDeltaTime = 1 / 60f;
while (skipDuration > 0) {
float dt = skipDuration < stepDeltaTime ? skipDuration : stepDeltaTime;
effect.update(dt);
skipDuration -= stepDeltaTime;
}

Java code with timestamp

I am recently working with an algorithm and implementing it in JAVA. In which I put a timer for computing the time taken by particular phase of algorithm. The code for timer is something like this.
static long start = 0;
long time = System.currentTimeMillis() - start;
System.out.printf("Took %.3f%n", time/1e3);
And the output of this code is
Took 6.807
Now what is the unit of time in this output. Is it millisecond or microsecond or nano second or just second? And what needs to be done with this code to get the output time in millisecond? Thank You in advance.
Here is the explanation:
System.currentTimeMillis() returns the current time in milliseconds. Check the link.
Dividing it with 1e3 (it's 1*103, that's 1000) converts the time to seconds, because one second contains 1000 milliseconds.
However I don't understand the usage of the key word static in the first line.

Fps algorithm error with systemtime

I'm having some trouble with an FPS algorithm I have tried to implement into my simulator. The general idea is that I want 60 to be the maximum amount of tick-render cycles per second. Here is my code:
public void run() {
x = 0; //tick is set to 0 originally
lastT = System.currentTimeMillis(); //system time in milliseconds
//tick-render cycle
while(running == true){
currentT = System.currentTimeMillis();
deltaT += currentT - lastT;
lastT = currentT;
if(deltaT/tPerTick >= 1){
tick();
render();
deltaT = 0;
}
}
stop(); //stops thread when running =! true
}
The constant 'tPerTick' is defined as follows
double tPerTick = 1000 / 60
Throughout my development of this program I thought that this algorithm was working perfectly, it was only when I traced this algorithm to confirm that I found an issue. Every time the loop cycles (iterates? I'm not sure what the correct word is here) the if statement is found to be true and therefore the tick-render cycle is executed. I did some more tracing (to find why this was happening) and found that the values for deltaT are always well over tPerTick, like way way over (in some cases 19 seconds even though this is clearly not the case). Is there an error somewhere in my code? I think that I must be either using System.currentTimeMillis() wrong or am tracing the algorithm incorrectly.
In the actual simulation it seems to be working fine (not sure why). When I draw the graphics I pass 'x' (the tick) in and write the time to the screen as x / 60 seconds.
Answering my own question.
System.currentTimeMillis();
Gets the current system time. If you are going through the algorithm manually in debug mode, 'deltaT' is going to be very large since it will be equal to the time that you take to manually trace through the algorithm.

Calculating time difference in Milliseconds

I am making a call to a method by passing ipAddress and it will return back the location of ipAddress like Country, City, etc etc. So I was trying to see how much time it is taking for each call. So I set the start_time before making call to method and end_time after making a call. So sometimes I get difference as 0. And resp contains the valid response.
long start_time = System.currentTimeMillis();
resp = GeoLocationService.getLocationIp(ipAddress);
long end_time = System.currentTimeMillis();
long difference = end_time-start_time;
So that means sometimes it is taking 0 ms to get the response back. Any suggestions will be appreciated.
Try this
long start_time = System.nanoTime();
resp = GeoLocationService.getLocationByIp(ipAddress);
long end_time = System.nanoTime();
double difference = (end_time - start_time) / 1e6;
I pretty much like the (relatively) new java.time library: it's close to awesome, imho.
You can calculate a duration between two instants this way:
import java.time.*
Instant before = Instant.now();
// do stuff
Instant after = Instant.now();
long delta = Duration.between(before, after).toMillis(); // .toWhatsoever()
API is awesome, highly readable and intuitive.
Classes are thread-safe too. !
References: Oracle Tutorial, Java Magazine
No, it doesn't mean it's taking 0ms - it shows it's taking a smaller amount of time than you can measure with currentTimeMillis(). That may well be 10ms or 15ms. It's not a good method to call for timing; it's more appropriate for getting the current time.
To measure how long something takes, consider using System.nanoTime instead. The important point here isn't that the precision is greater, but that the resolution will be greater... but only when used to measure the time between two calls. It must not be used as a "wall clock".
Note that even System.nanoTime just uses "the most accurate timer on your system" - it's worth measuring how fine-grained that is. You can do that like this:
public class Test {
public static void main(String[] args) throws Exception {
long[] differences = new long[5];
long previous = System.nanoTime();
for (int i = 0; i < 5; i++) {
long current;
while ((current = System.nanoTime()) == previous) {
// Do nothing...
}
differences[i] = current - previous;
previous = current;
}
for (long difference : differences) {
System.out.println(difference);
}
}
}
On my machine that shows differences of about 466 nanoseconds... so I can't possibly expect to measure the time taken for something quicker than that. (And other times may well be roughly multiples of that amount of time.)
Since Java 1.5, you can get a more precise time value with System.nanoTime(), which obviously returns nanoseconds instead.
There is probably some caching going on in the instances when you get an immediate result.
From Java 8 onward you can try the following:
import java.time.*;
import java.time.temporal.ChronoUnit;
Instant start_time = Instant.now();
// Your code
Instant stop_time = Instant.now();
System.out.println(Duration.between(start_time, stop_time).toMillis());
//or
System.out.println(ChronoUnit.MILLIS.between(start_time, stop_time));
I do not know how does your PersonalizationGeoLocationServiceClientHelper works. Probably it performs some sort of caching, so requests for the same IP address may return extremely fast.
In the old days (you know, anytime before yesterday) a PC's BIOS timer would "tick" at a certain interval. That interval would be on the order of 12 milliseconds. Thus, it's quite easy to perform two consecutive calls to get the time and have them return a difference of zero. This only means that the timer didn't "tick" between your two calls. Try getting the time in a loop and displaying the values to the console. If your PC and display are fast enough, you'll see that time jumps, making it look as though it's quantized! (Einstein would be upset!) Newer PCs also have a high resolution timer. I'd imagine that nanoTime() uses the high resolution timer.
In such a small cases where difference is less than 0 milliseconds you can get difference in nano seconds as well.
System.nanoTime()
You can use
System.nanoTime();
To get the result in readable format, use
TimeUnit.MILLISECONDS or NANOSECONDS

Java: What is the unit of the difference of two System.currentTimeMillis?

What is the unit of the difference of two System.currentTimeMillis ?
start = System.currentTimeMillis();
longoperation();
elapsedTime = System.currentTimeMillis() - start;
What is the unit of elapsed time here. It doesn't look like milliseconds.
Is the above code segment the right way to find the time taken to execute longoperation()?
Yes, it is in milliseconds. Bear in mind that the difference is not absolutely correct and may vary.
It is ms (MiliSecond) only, you are doing right.
You can ignore time taken while calculating millis
It is milliseconds and your code looks correct.
Whatever you are doing is correct. If you want the time in seconds, simply divide it by 1000.
long start = System.currentTimeMillis();
longoperation();
long elapsedTime = (System.currentTimeMillis() - start)/1000;
Yes, currentTimeMillis() returns you a milliseconds value.
On Windows, it used to be the case that the returned value had quite low resolution, and so was only accurate to something like 10ms. I'm not certain whether this is still the case as I haven't used Windows for a few years - but if your longoperation() actually takes just a few millis, and you're running on Windows, then you may see elapsedTime variously being 10ms or 0ms.

Categories

Resources