Reputation: 1
I have written some code using System.nanoTime()
and the output did always have two trailing zeros. Now I wondered if that behavior is normal. I tried it on two laptops and it always stayed that inprecise, even though I remember having seen a particular precise value of System.nanoTime()
somewhere in the past.
Here´s the code:
long beginTime = System.nanoTime();
for (int i = 0; i < 5; i++) {
// doing something for time to pass
long tpValue = 1;
for (int j = 0; j < 14862; j++) {
long value = 0x4b38e;
value &= System.nanoTime();
tpValue = (tpValue & value) | (tpValue ^ value);
}
long timePassed = System.nanoTime() - beginTime;
System.out.println("Time passed: " + timePassed + " ns;" +
" Value calculated to pass time: " + tpValue);
}
In this example on my device the value of tpValue
would always be the same unless I divide System.nanoTime()
by 1000.
Here the output:
Time passed: 921000 ns; Value calculated to pass time: 308109
Time passed: 9554500 ns; Value calculated to pass time: 308109
Time passed: 10551800 ns; Value calculated to pass time: 308109
Time passed: 11530700 ns; Value calculated to pass time: 308109
Time passed: 12519400 ns; Value calculated to pass time: 308109
Upvotes: 0
Views: 74
Reputation: 340188
The Answer by HopefullyHelpful is correct and smart.
I can add my own pedestrian simple code showing counts of nanoseconds to the singles place.
for ( int i = 1 ; i <= 10 ; i ++ )
{
System.out.println( System.nanoTime() ) ;
}
See this code run at Ideone.com.
15463866040482559
15463866041067009
15463866041111618
15463866041153989
15463866041196195
15463866041238231
15463866041279697
15463866041321311
15463866041362851
15463866041404462
And, by the way, to calculate elapsed nanos, I would use the handy Duration
class.
long start = System.nanoTime() ;
…
Duration d = Duration.ofNanos( System.nanoTime() - start ) ;
System.out.println( d ) ; // Duration#toString generates text in standard ISO 8601 format.
System.out.println( d.toNanos() ) ;
PT0.000843285S
843285
Upvotes: 2
Reputation: 1819
From https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#nanoTime--
This method provides nanosecond precision, but not necessarily nanosecond resolution (that is, how frequently the value changes) - no guarantees are made except that the resolution is at least as good as that of currentTimeMillis().
Also your test has a few flaws, you're not polling nanotime very often. You basically have only 5 meaningful calls to long timePassed = System.nanoTime() - beginTime;
And you're not looking at System.nanoTime()
directly, but at a difference of 2 System.nanoTime()
values.
If you want to test resolution you can do any of the following
1.test your hypothesis that all values have a trailing 00 or same last 2 digits:
while(true) {
long time = System.nanoTime();
if(time % 100 != 0) {
System.out.println(time)
}
}
2.Or you can print the difference between a lot of call values, afterwards can filter all multiples of the smallest value with %
and see if that is the actual resolution:
while(true) {
long time = System.nanoTime();
System.out.println(System.nanoTime()-time);
}
Upvotes: 4