Getting precise elapsed time using Java to the Millisecond

十年热恋 提交于 2021-01-28 12:12:55

问题


I've been searching for an answer to my dilemma and have found some useful tips but nothing that addresses my specific question, so I was hoping someone here might be able to help me out.

I'm trying to get a precise elapsed time to the millisecond in Java. I'm using System.nanoTime() to get the current time and implementing it in the following code. Mind you, this was code that I used to test it's precision.

long startTime = System.nanoTime()/1000000;
while (true)
{
System.out.println((System.nanoTime()/1000000)-startTime);
}

A portion of the output looks like this.

1110
1112
1112
1113
1114
1118
1120

The first digit is the number of seconds, the second, tenths of a second, the third, hundredths, and then the last is thousandths. You can't see it here, but I have precision to the hundredths place - no skipped or repeated numbers. The thousandths, though, is far from precise. 0 -> 2 -> 2 -> 3 -> 4 -> 8 -> 0. For what I'm doing, I need precision to the thousandths place and from all I have read it seems like System.nanoTime() should be able to provide precision to the millisecond.

Am I doing something wrong or is there another way I can get precision to the millisecond?


回答1:


There are two factors here.

First, even System.nanoTime() is not necessarily really precise - it just uses the finest clock available (and does not follow clock changes, so it never goes backwards or jumps forward).

Second, your Java program is not the only program running on your computer - so your code (which essentially is the calling of the native nanoTime function and the output of the result) will take differently much time each time. For example, it may be that one output needs more than a full millisecond while another takes only a half or less.

Try to output some more digits (i.e. divide by a smaller number), the results will be helpful to understand.




回答2:


Divide by 1 million after the subtraction, and use a long literal.

long startTime = System.nanoTime();

while (true)
{
    System.out.println((System.nanoTime() - startTime)/1000000L);
}

Demo (updated): http://ideone.com/X5RRa




回答3:


java.time

The old date-time classes are now supplanted by the java.time classes.

The java.time classes support a resolution up to nanoseconds. But remember that the actual resolution and accuracy depend upon the hardware clock of the host computer. So your results will vary.

Instant instant = Instant.now();  

2016-01-02T12:34:56.123456789Z

To reduce from possible nanosecond resolution to milliseconds, call the Instant::truncatedTo method.

Instant instantTruncated = Instant.now().trucatedTo( ChronoUnit.MILLIS );

2016-01-02T12:34:56.123Z

Keep in mind that most computer hardware clocks are not very accurate in the granularities of milliseconds-microsecond-nanoseconds.


Minor note: While the java.time classes support storing nanosecond resolution, in Java 8 the legacy implementation of Clock is limited to capturing the current moment with only milliseconds rather than nanoseconds. Java 9 brings a fresh implementation of Clock so the current moment can be captured in up to nanosecond resolution depending on the capability of your host computer clock hardware and host OS.



来源:https://stackoverflow.com/questions/5476250/getting-precise-elapsed-time-using-java-to-the-millisecond

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!