I know that System.nanoTime() is now the preferred method for measuring time over System.currentTimeInMillis() . The first obvious reason is nanoTime() gives more precise timing and the other reason I read that the latter is affected by adjustments to the system’s real-time clock. What does "getting affected by systems real-time clock " mean ?
In this case I've found following blog post excerpt useful:
If you are interested in measuring absolute time then always use
System.currentTimeMillis(). Be aware that its resolution may be quite
coarse (though this is rarely an issue for absolute times.)
If you are interested in measuring/calculating elapsed time, then
always use System.nanoTime(). On most systems it will give a
resolution on the order of microseconds. Be aware though, this call
can also take microseconds to execute on some platforms.
Clocks and Timers - General Overview by David Holmes
Since System.currentTimeMillis() is relying on the systems time of day clock, adjustments to the time are legitimate, in order to keep it on time.
What means adjustments here? Take for instance a look at the description of CLOCK_REALTIME from Linux:
System-wide clock that measures real (i.e., wall-clock) time.
Setting this clock requires appropriate privileges. This clock is
affected by discontinuous jumps in the system time (e.g., if the
system administrator manually changes the clock), and by the
incremental adjustments performed by adjtime(3) and NTP.
Just check the JavaDoc of the methods:
System.nanoTime()
"... This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. ..."
System.currentTimeMillis()
"... Returns the current time in milliseconds. ..."
So as you can see if the system time changes during the measurement using the System.currentTimeMillis(), the interval you measure will change too. However, it will not change when measuring the interval using the System.nanoTime() method.
It means that the value that System.currentTimeMillis() returns is obtained from the internal clock of the machine. If a sysadmin (or NTP) changes the time, for example if the clock is found to be running 5 minutes fast and the sysadmin goes and corrects it, System.currentTimeMillis() will be affected. This means that you can even see the value decrease, and if you use it to measure intervals the timings can be off. You may even measure negative timings.
System.nanoTime() on the other hand returns a value that is derived from some internal CPU counter/clock. The time measured by this clock cannot be changed by any user or program. This means that it will be more reliable for timing. But the CPU clock is reset on poweroff so it's not useful for finding the current "wall-clock" time.
Related
I'd like to know how to calculate the CPU Cycle for a function in Java or Python.
I tried out in Java with:
(OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
osbean.getProcessCpuTime();
But no results.
in Python,
use timeit.default_timer(); it uses the most accurate option for your platform. in Ubuntu, this will use time.time() instead.
timeit.default_timer()Define a default timer, in a platform-specific manner. On Windows, time.clock() has microsecond granularity, but time.time()‘s granularity is 1/60th of a second. On Unix, time.clock() has 1/100th of a second granularity, and time.time() is much more precise. On either platform, default_timer() measures wall clock time, not the CPU time. This means that other processes running on the same computer may interfere with the timing.
in JAVA,
System.currentTimeMillis() will only ever measure wall-clock time, never CPU time.
If you need wall-clock time, then System.nanoTime() is often more precise (and never worse) than currentTimeMillis().
ThreadMXBean.getThreadCPUTime() can help you find out how much CPU time a given thread has used. Use ManagementFactory.getThreadMXBean() to get a ThreadMXBean and Thread.getId() to find the id of the thread you're interested in. Note that this method need not be supported on every JVM!
Accuracy Vs. Precision
What I would like to know is whether I should use System.currentTimeMillis() or System.nanoTime() when updating my object's positions in my game? Their change in movement is directly proportional to the elapsed time since the last call and I want to be as precise as possible.
I've read that there are some serious time-resolution issues between different operating systems (namely that Mac / Linux have an almost 1 ms resolution while Windows has a 50ms resolution??). I'm primarly running my apps on windows and 50ms resolution seems pretty inaccurate.
Are there better options than the two I listed?
Any suggestions / comments?
If you're just looking for extremely precise measurements of elapsed time, use System.nanoTime(). System.currentTimeMillis() will give you the most accurate possible elapsed time in milliseconds since the epoch, but System.nanoTime() gives you a nanosecond-precise time, relative to some arbitrary point.
From the Java Documentation:
public static long nanoTime()
Returns the current value of the most precise available system timer, in nanoseconds.
This method can only be used to
measure elapsed time and is not
related to any other notion of system
or wall-clock time. The value returned
represents nanoseconds since some
fixed but arbitrary origin time (perhaps in
the future, so values may be
negative). This method provides
nanosecond precision, but not
necessarily nanosecond accuracy. No
guarantees are made about how
frequently values change. Differences
in successive calls that span greater
than approximately 292 years (263
nanoseconds) will not accurately
compute elapsed time due to numerical
overflow.
For example, to measure how long some code takes to execute:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
See also: JavaDoc System.nanoTime() and JavaDoc System.currentTimeMillis() for more info.
Since no one else has mentioned this…
It is not safe to compare the results of System.nanoTime() calls between different JVMs, each JVM may have an independent 'origin' time.
System.currentTimeMillis() will return the (approximate) same value between JVMs, because it is tied to the system wall clock time.
If you want to compute the amount of time that has elapsed between two events, like a stopwatch, use nanoTime(); changes in the system wall-clock make currentTimeMillis() incorrect for this use case.
Update by Arkadiy: I've observed more correct behavior of System.currentTimeMillis() on Windows 7 in Oracle Java 8. The time was returned with 1 millisecond precision. The source code in OpenJDK has not changed, so I do not know what causes the better behavior.
David Holmes of Sun posted a blog article a couple years ago that has a very detailed look at the Java timing APIs (in particular System.currentTimeMillis() and System.nanoTime()), when you would want to use which, and how they work internally.
Inside the Hotspot VM: Clocks, Timers and Scheduling Events - Part I - Windows
One very interesting aspect of the timer used by Java on Windows for APIs that have a timed wait parameter is that the resolution of the timer can change depending on what other API calls may have been made - system wide (not just in the particular process). He shows an example where using Thread.sleep() will cause this resolution change.
As others have said, currentTimeMillis is clock time, which changes due to daylight saving time (not: daylight saving & time zone are unrelated to currentTimeMillis, the rest is true), users changing the time settings, leap seconds, and internet time sync. If your app depends on monotonically increasing elapsed time values, you might prefer nanoTime instead.
You might think that the players won't be fiddling with the time settings during game play, and maybe you'd be right. But don't underestimate the disruption due to internet time sync, or perhaps remote desktop users. The nanoTime API is immune to this kind of disruption.
If you want to use clock time, but avoid discontinuities due to internet time sync, you might consider an NTP client such as Meinberg, which "tunes" the clock rate to zero it in, instead of just resetting the clock periodically.
I speak from personal experience. In a weather application that I developed, I was getting randomly occurring wind speed spikes. It took a while for me to realize that my timebase was being disrupted by the behavior of clock time on a typical PC. All my problems disappeared when I started using nanoTime. Consistency (monotonicity) was more important to my application than raw precision or absolute accuracy.
System.nanoTime() isn't supported in older JVMs. If that is a concern, stick with currentTimeMillis
Regarding accuracy, you are almost correct. On SOME Windows machines, currentTimeMillis() has a resolution of about 10ms (not 50ms). I'm not sure why, but some Windows machines are just as accurate as Linux machines.
I have used GAGETimer in the past with moderate success.
Yes, if such precision is required use System.nanoTime(), but be aware that you are then requiring a Java 5+ JVM.
On my XP systems, I see system time reported to at least 100 microseconds 278 nanoseconds using the following code:
private void test() {
System.out.println("currentTimeMillis: "+System.currentTimeMillis());
System.out.println("nanoTime : "+System.nanoTime());
System.out.println();
testNano(false); // to sync with currentTimeMillis() timer tick
for(int xa=0; xa<10; xa++) {
testNano(true);
}
}
private void testNano(boolean shw) {
long strMS=System.currentTimeMillis();
long strNS=System.nanoTime();
long curMS;
while((curMS=System.currentTimeMillis()) == strMS) {
if(shw) { System.out.println("Nano: "+(System.nanoTime()-strNS)); }
}
if(shw) { System.out.println("Nano: "+(System.nanoTime()-strNS)+", Milli: "+(curMS-strMS)); }
}
For game graphics & smooth position updates, use System.nanoTime() rather than System.currentTimeMillis(). I switched from currentTimeMillis() to nanoTime() in a game and got a major visual improvement in smoothness of motion.
While one millisecond may seem as though it should already be precise, visually it is not. The factors nanoTime() can improve include:
accurate pixel positioning below wall-clock resolution
ability to anti-alias between pixels, if you want
Windows wall-clock inaccuracy
clock jitter (inconsistency of when wall-clock actually ticks forward)
As other answers suggest, nanoTime does have a performance cost if called repeatedly -- it would be best to call it just once per frame, and use the same value to calculate the entire frame.
System.currentTimeMillis() is not safe for elapsed time because this method is sensitive to the system realtime clock changes of the system.
You should use System.nanoTime.
Please refer to Java System help:
About nanoTime method:
.. 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()..
If you use System.currentTimeMillis() your elapsed time can be negative (Back <-- to the future)
I've had good experience with nanotime. It provides wall-clock time as two longs (seconds since the epoch and nanoseconds within that second), using a JNI library. It's available with the JNI part precompiled for both Windows and Linux.
one thing here is the inconsistency of the nanoTime method.it does not give very consistent values for the same input.currentTimeMillis does much better in terms of performance and consistency,and also ,though not as precise as nanoTime,has a lower margin of error,and therefore more accuracy in its value. i would therefore suggest that you use currentTimeMillis
I am trying to implement a timer, it may be used for short (seconds) events, or longer (hours, etc) events.
Ideally it should persist over periods when the CPU is off, for example, battery has died. If I set the start time using System.currentTimeMillis() and end time using the same function, it works in almost all cases, except during periods like leap seconds, leap years, daylight savings time changes, etc... Or, if the user just changes the time (I've verified this). This is on an Android system, btw.
Instead, if I used System.nanoTime(), in addition to potentially being more accurate, it won't have the usual "hard time" issues with time changes, etc. My question is, does System.nanoTime() measure nanoseconds from some arbitrary time, in "hard time"? I'm not sure what the proper term is, but for example, will System.nanoTime() ran at X, then X+1 hour later, the system is shut off (dead battery on Android device, for example), then X+10 hours, the system is started, will running System.nanoTime() at this point return 10 hours? Or will it return 1 hour (since the "counter" that nanoTime uses may not be running when system is off/asleep?).
android.os.SystemClock.elapsedRealtime() - milliseconds since the system was booted including time spent in sleep state. This should be your best bet.
I dont think you can measure the switched off time in android.
For more info it might be better to check android system clock page. http://developer.android.com/reference/android/os/SystemClock.html
It is undefined:
"The value returned represents nanoseconds since some fixed but
arbitrary origin time (perhaps in the future, so values may be
negative). The same origin is used by all invocations of this method
in an instance of a Java virtual machine; other virtual machine
instances are likely to use a different origin."
For simplicity, we'll say when you run it at time X, the origin is X (this is allowed). That means it will return 0 then, and within the VM instance, time will then elapse at the same rate as a normal clock.
When you use Thread.sleep, that doesn't change the VM instance, so it isn't treated specially.
However, after the device is rebooted, you're in a different VM instance. Therefore, X is no longer guaranteed to be the origin.
Is it correct to compare two values resulting from a call to System.nanoTime() on two different machines? I would say no because System.nanoTime() returns a nanosecond-precise time relative to some arbitrary point time by using the Time Stamp Counter (TSC) which is processor dependent.
If I am right, is there a way (in Java) to capture an instant on two different machines and to compare (safely) these values with at least a microsecond precision or even nanotime precision?
System.currentTimeMillis() is not a solution because it is not returning a linearly increasing number of time stamps. The user or services such as NTP can change the system clock at any time and the time will leap back and forward.
You might want to look into the various clock synchronization algorithms available. Apparently the Precision Time Protocol can get you within sub-microsecond accuracy on a LAN.
If you don't need a specific time value but rather would like to know the ordering of various events, you could for instance use Lamport timestamps.
You cannot use nanoTime between two different machines. For the Java API docs:
This method can only be used to measure elapsed time and is not
related to any other notion of system or wall-clock time. The value
returned represents nanoseconds since some fixed but arbitrary time
(perhaps in the future, so values may be negative).
There's no guarantee that nanoTime is relative to any timebase.
This is a processor & OS dependent Q. Looking at POSIX clocks, for example, there are high precision time of day aware timestamps (e.g. CLOCK_REALTIME returns a nano epoch time value) and high precision arbitrary time timestamps (e.g. CLOCK_MONOTONIC) (NB: the difference between these 2 is nicely explained in this answer).
The latter is often something like time since the box was booted and therefore there's no way to accurately compare them across servers unless you have high precision clock sync (e.g. PTP as referenced in the other answer) in the first place (as then you'd be able to share an offset between them).
Whether NTP is good enough for you depends on what you're trying to measure. For example if you're trying to measure an interval of a few hundred micros (e.g. boxes connected to the same switch) then your results will be rough, at the other extreme NTP can be perfectly good if your servers are in different geographical locations entirely (e.g. London to NY) which means the clock sync effect (as long as it's not way way off) is swamped by the latency between the locations.
FWIW the JNI required to access such clocks from java is pretty trivial.
You can synchronize the time to current time millis. However even if you use NTP this can drift by 1 ms to 10 ms between machines. The only way to be micro-second synchronization between machines is to use specialist hardware.
nanoTime is guaranteed to be determined the same way or have the same resolution on two different OSes.
I'm writing a simple timer in Java. It has Start and Stop buttons, along with a text view showing how much time has passed since the timer was started.
It's implemented by setting initial time with System.currentTimeMillis() and updating current value each second in a loop.
The problem is that if I change system time while the timer is running, the whole measurement fails. E.g., if I set time back one month, the timer shows negative value as currentTimeMillis() now returns less value than initial.
So, how do I calculate time delta which would be independent from the system time? It would be also great to make this solution cross-platform.
Use:
System.nanoTime()
This should do it. It doesn't take the system time into account, and can only be used to measure elapsed time. Which is what you want. You need to divide by 1 million to get the elapsed milliseconds. See also the Javadocs.
System.nanoTime();
From Javadoc:
This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time.
Use time web services . for example this or this or this
You can install demon like NTP, system time jumping in any directions has a lot of issues and can lead to quite a lot of other problems.
System.nanoTime() not necessarily depend on the system clock - but it can - just make sure the system time is correctly progressing.
Modifying system time is a privileged operation, so it someone does that they shall know better.
Here is a bug 13 years of age regarding the same case: http://bugs.sun.com/view_bug.do?bug_id=4290274
HTH