Timer accuracy in java - java

I'm timing some things, which I can't just put in a long loop. And I need to time them to see how long they take to complete, but it seems like the timer has a 15-16 ms accuracy in java? How can i get around this?

Have you tried using System.nanoTime()?
From the Javadoc:
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 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;

Clocks and Timers - General Overview
Java Programming API's for Clocks and Timers The absolute
"time-of-day" clock is represented by
the System.currentTimeMillis() method,
that returns a millisecond
representation of wall-clock time in
milliseconds since the epoch. As such
it uses the operating system's "time
of day" clock. The update resolution
of this clock is often the same as the
timer interrupt (eg. 10ms), but on
some systems is fixed, independent of
the interrupt rate.
The relative-time clock is represented
by the System.nanoTime() method that
returns a "free-running" time in
nanoseconds. This time is useful only
for comparison with other nanoTime
values. The nanoTime method uses the
highest resolution clock available on
the platform, and while its return
value is in nanoseconds, the update
resolution is typically only
microseconds. However, on some systems
there is no choice but to use the same
clock source as for
currentTimeMillis() - fortunately this
is rare and mostly affects old Linux
systems, and Windows 98.

Related

Which one is recommended: Instant.now().toEpochMilli() or System.currentTimeMillis()

In Java, we can have many different ways to get the current timestamp, but which one is recommended:
Instant.now().toEpochMilli() or System.currentTimeMillis()
Both are fine. And neither is recommended except for a minority of purposes.
What do you need milliseconds since the epoch for?
In Java, we can have many different ways to get the current timestamp,
For current timestamp just use Instant.now(). No need to convert to milliseconds.
Many methods from the first years of Java, also many in the standard library, took a long number of milliseconds since the epoch as argument. However, today I would consider that old-fashioned. See if you can find — or create — or more modern method that takes for instance an Instant as argument instead. Go object-oriented and don’t use a primitive long. It will make your code clearer and more self-explanatory.
As Eliott Frisch said in a comment, if this is for measuring elapsed time, you may prefer the higher resolution of System.nanoTime().
If you do need milliseconds since the epoch
Assuming that you have good reasons for wanting a count of milliseconds since the epoch, …
which one is recommended: Instant.now().toEpochMilli() or
System.currentTimeMillis()[?]
Opinions differ. Some will say that you should use java.time, the modern date and time API, for all of your date and time work. This would imply Instant here. Unsg java.time is generally a good habit since the date and time classes from Java 1.0 and 1.1 (Date, Calendar, TimeZone, DateFormat, SimpleDateFormat and others) are poorly designed and now long outdated, certainly not any that we should use anymore. On the other hand I am not aware of any design problem with System.curremtTimeMillis() in particular (except what I mentioned above about using a long count of milliseconds at all, which obviously is intrinsic to both Instant.now().toEpochMilli() and System.currentTimeMillis()).
If there is a slight performance difference between the two, I have a hard time imagining the situation where this will matter.
Take the option that you find more readable and less surprising in your context.
Similar questions
JSR 310 :: System.currentTimeMillis() vs Instant.toEpochMilli() :: TimeZone
Java current time different values in api
As per my understanding Instant.now().toEpochMilli() is better as Java-8 onward usage of Instant has been recommended.
Also, it works based on timeline and instant represents a specific moment on that timeline.
In case of java.lang.System.currentTimeMillis() method it returns the current time in milliseconds. The granularity of the value depends on the underlying operating system and may be larger.
Hence, to be consistent altogether use Instant.
I want to add that System.nanoTime() is less about precision but more about accuracy.
System.currentTimeMillis() is based on the system clock, which is, most of the time, based on a quartz clock inside a computer. It is not accurate and it drifts. (VM is even worse since you don't have a physical clock and have to sync with the host) When your computer syncs this quartz clock with a global clock, you might even observe your clock jumps backward/forward because your local clock is too fast or slow.
On the other hand, System.nanoTime() is based on a monotonic clock. This clock has nothing to do with the actual time we humans speak. It only moves forward at a constant pace. It does not drift like the quartz clock and there is no sync required. This is why it is perfect for measuring elapses.
For what it's worth, I've done a quick non-ideal performance test comparing the two methods.
On my system (Ubuntu 20.04, OpenJDK 17.0.4), running System.currentTimeMillis ten million times takes cca 230ms while running Instant.now().toEpochMilli() ten million times takes cca 370ms.
import java.time.Instant;
public class A {
public static void main(String[] args) {
long a = 0;
long start = System.currentTimeMillis();
for (int i = 0; i < 10_000_000; i++) {
//a += Instant.now().toEpochMilli();
a += System.currentTimeMillis();
}
System.out.println(a);
System.out.println(System.currentTimeMillis() - start);
}
}

Equivalent of Erlang now() in Java

I am working on a project which requires timestamps for running threads. In Erlang, when we do now() we get something like
{1529,709564,578215} which represent {megaseconds, seconds, microseconds}
since epoch. So, for two processes spawned at the same time, I can get same microseconds value. Is there a way to replicate this function in Java?
I know about Date.getTime() which gives us the milliseconds since epoch time, but it does not serve the purpose since I cannot get a unique microsecond value from it after dividing by order of magnitude.
Any alternative?
System.out.println(Instant.now());
Output just now was:
2018-06-23T05:16:45.768006Z
On the Java 10 on my Mac it gave microsecond precision. Since Java 9 it will on many operating systems, maybe not all. Instant.now() returns an Instant. An Instant is implemented as seconds and nanoseconds since the epoch, and you can get out those individually if you want.

System.currentTimeMillis measuring time

When I use System.currentTimeMillis() to measure the time, is it safe?
E.g. When a time-shift happens (summer->winter time) will this produce an error?
No, System.currentTimeMillis() returns the number of elapsed milliseconds since the Unix epoch (midnight at the start of January 1st 1970, UTC). This does not depend on your local time zone at all.
In other words, if you call it once per second, it will always increase by about 1000 (the "about" is only due to clock accuracy and the impossibility of the calls being exactly 1 second apart). It doesn't matter if your local time zone changes its offset from UTC, or if you even change your whole time zone - that will be irrelevant.
In theory, leap seconds make all of this trickier - but in practice most applications can get away with notionally sticking their fingers in their ears and saying "I'm not at home to Mr Leap Second."
System.currentTimeMillis() will return the milliseconds since epoch (1/1/1970 00:00:00). How those are interpreted is a completely different story (and summer/winter time as well as timezone belong to the interpretation part). So yes, it would be save.

Getting nanos into a java.sql.Timestamp

http://docs.oracle.com/javase/6/docs/api/java/sql/Timestamp.html
The only non-deprecated ctor takes millis. Is there no way to ask for 'now' including nanos.
getNanos()/setNanos(int) on Timestamp exists to support databases that return the timestamp data type with nanosecond precision.
Java does not have a means to get the current time with nanosecond precision. System.nanoTime() returns elapsed nanoseconds from some unknown epoch chosen by the JVM. It is useful for measuring elapsed time between two calls of System.nanoTime(). Even then while System.nanoTime() can measure elapsed time between calls to nanosecond precision it is not necessarily accurate to nanosecond precision as mentioned in the javadocs.
As has been noted in comments on other answers, System.nanoTime() doesn't really return any meaningful values regarding time in nanoseconds.
I would like to point to this discussion from SO which points out why we can't get better accuracy on our time measurements. It would appear to imply that it is not really possible to do as you ask, and that it would be against some Java design goals to try and include this ability, due to portability and platform constraints.
So, in answer to your question, I would say no, but only based upon the answers of people with more rep than me.

How to get the microseconds from a Date?

I am trying to get microseconds from a Date, but I can't.
Date date = new Date()
No, Date only stores values to millisecond accuracy. If you want microsecond accuracy, you might want to look at JSR-310, or java.sql.Timestamp as a bit of a hack - but don't expect any of the built-in classes such as Calendar and DateFormat to handle anything beyond milliseconds.
If you're trying to perform timing (e.g. for benchmarking) you should use System.nanoTime, but that should only be used for stopwatch-like use cases - it doesn't give you the "current wallclock time" in a meaningful way.
What I do is find the difference between the currentTimeMillis and the nanoTime() at regular intervals (as this drifts quite a bit) and use nanoTime() + OFFSET for a currentTimeNS. (More specificity I use the RDTSC machine code instruction, which comes with even more quibbles ;)
However, its is less accurate than currenTimeMillis() over time which itself can drifts by many milli-seconds in an hour.
It only really useful if you understand its limitations.
To measure time in microseconds you need to use the System.nanoTime() function which will return a time in microseconds based on the most accurate clock available to your system.
To the user this acts in pretty much the same way as System.currentTimeMilis() does for milliseconds, you simply define your start and end times and then negate the difference to find out how long an action took. For example:
long startTime = System.nanoTime();
//Do some kind of processing;
//loop, IO, whatever you want to measure
long endTime = System.nanoTime();
long elapsedTime = endTime - startTime;
The last bit can be shorted, I've left it verbose for simplicity:
long elapsedTime = System.nanoTime() - startTime;
This should not be used to measure real time as it has very little meaning or guarantee that it is even comparable to it. All of the above information is available from the Java API documentation for System.

Categories