http://stackoverflow.com/questions/510462/is-system-nanotime-completely-useless
|
As documented in the blog post Beware of System.nanoTime() in Java, on x86 systems, Java's System.nanoTime() returns the time value using a CPU specific counter. Now consider the following case I use to measure time of a call:
Now in a multi-core system, it could be that after measuring time1, the thread is scheduled to a different processor whose counter is less than that of the previous CPU. Thus we could get a value in time2 which is less than time1. Thus we would get a negative value in timeSpent. Considering this case, isn't it that System.nanotime is pretty much useless for now? I know that changing the system time doesn't affect nanotime. That is not the problem I describe above. The problem is that each CPU will keep a different counter since it was turned on. This counter can be lower on the second CPU compared to the first CPU. Since the thread can be scheduled by the OS to the second CPU after getting time1, the value of timeSpent may be incorrect and even negative. |
|||||||||||||
|
|
That post is wrong, and
So, on Windows, this was a problem up until WinXP SP2, but it isn't now. I can't find a part II (or more) that talks about other platforms, but that article does include a remark that Linux has encountered and solved the same problem in the same way, with a link to the FAQ for clock_gettime(CLOCK_REALTIME), which says:
So, if Holmes's link can be read as implying that There's no mention of SPARC or Solaris, sadly. And of course, we have no idea what IBM JVMs do. But Sun JVMs on modern Windows and Linux get this right. EDIT: This answer is based on the sources it cites. But i still worry that it might actually be completely wrong. Some more up-to-date information would be really valuable. I just came across to a link to afour year newer article about Linux's clocks which could be useful. |
|||||||||||||||||
|
|
I did a bit of searching and found that if one is being pedantic then yes it might be considered useless...in particular situations...it depends on how time sensitive your requirements are... Check out this quote from the Java Sun site:
Java also has a caveat for the nanoTime() method:
It would seem that the only conclusion that can be drawn is that nanoTime() cannot be relied upon as an accurate value. As such, if you do not need to measure times that are mere nano seconds apart then this method is good enough even if the resulting returned value is negative. However, if you're needing higher precision, they appear to recommend that you use JAVA RTS. So to answer your question...no nanoTime() is not useless....its just not the most prudent method to use in every situation. |
|||||||||||||||||||||
|
|
No need to debate, just use the source. Here, SE 6 for Linux, make your own conclusions:
|
|||||
|
|
You might like this better: http://juliusdavies.ca/nanotime/ But it copies a DLL or Unix .so (shared object) file into the current user's home directory so that it can call JNI. Some background information is on my site at: http://juliusdavies.ca/posix_clocks/clock_realtime_linux_faq.html |
|||||
|
|
Absolutely not useless. Timing aficionados correctly point out the multi-core problem, but in real-word applications it is often radically better than currentTimeMillis(). When calculating graphics positions in frame refreshes nanoTime() leads to MUCH smoother motion in my program. And I only test on multi-core machines. |
|||
|
Linux corrects for discrepancies between CPUs, but Windows does not. I suggest you assume System.nanoTime() is only accurate to around 1 micro-second. A simple way to get a longer timing is to call foo() 1000 or more times and divide the time by 1000. |
|||||||||||||||||||||
|
|
I have seen a negative elapsed time reported from using System.nanoTime(). To be clear, the code in question is:
and variable 'elapsedNanos' had a negative value. (I'm positive that the intermediate call took less than 293 years as well, which is the overflow point for nanos stored in longs :) This occurred using an IBM v1.5 JRE 64bit on IBM P690 (multi-core) hardware running AIX. I've only seen this error occur once, so it seems extremely rare. I do not know the cause - is it a hardware-specific issue, a JVM defect - I don't know. I also don't know the implications for the accuracy of nanoTime() in general. To answer the original question, I don't think nanoTime is useless - it provides sub-millisecond timing, but there is an actual (not just theoretical) risk of it being inaccurate which you need to take into account. |
|||||||||
|
|
This doesn't seem to be a problem on a Core 2 Duo running Windows XP and JRE 1.5.0_06. In a test with three threads I don't see System.nanoTime() going backwards. The processors are both busy, and threads go to sleep occasionally to provoke moving threads around. [EDIT] I would guess that it only happens on physically separate processors, i.e. that the counters are synchronized for multiple cores on the same die. |
|||||||||||||||||
|
|
Java is crossplatform, and nanoTime is platform-dependent. If you use Java - when don't use nanoTime. I found real bugs across different jvm implementations with this function. |
|||
|
No, it's not... It just depends on your CPU, check High Precision Event Timer for how/why things are differently treated according to CPU. Basically, read the source of your Java and check what your version does with the function, and if it works against the CPU you will be running it on. IBM even suggests you use it for performance benchmarking (a 2008 post, but updated). |
|||||
|
|
I am linking to what essentially is the same discussion where Peter Lawrey is providing a good answer. Why I get a negative elapsed time using System.nanoTime()? Many people mentioned that in Java System.nanoTime() could return negative time. I for apologize for repeating what other people already said.
It'd be cool if System.nanoTime() returned coreID where it executed. |
|||
|
The Java 5 documentation also recommends using this method for the same purpose.
|
|||
|
Also, |
|||
|
|
浙公网安备 33010602011771号