Setting Long in java jni call - java

I want to return microseconds from linux as java only has wall clock times to millisecond accuracy on systems with a monotonic clock.
My exposure to jni is limited so apologies if it's a silly question.
I believe I can either make a call in the c layer to gettimeofday and return the value as jlong:
private native long getMicros();
Or perhaps alternatively take a pointer to an address and then write the value to this address:
private native void getMicros(Long ptr);
The latter throws up lots of questions in my mind like "how does c know what the binary format of jlong is" and "how would I even do this!".
I just wondered if the latter might be faster than returning a value back across the jni layer.
Any thoughts most welcome.

http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#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 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;

Related

Fastest way to get nanos unix epoch time in Java

I currently do this to successfully get the current epoch time in nanos:
Instant inst = Instant.now();
long time = inst.getEpochSecond();
time *= 1000000000l;
time += inst.getNano();
However, it's a bit too slow for my use case, taking around 1us each call after the JVM has warmed up.
Is there a faster way to do it?
I'm happy with a solution that gives me the microseconds since epoch, as long as it's faster than the above.
What may work is to run:
long n1 = System.nanoTime();
long m = System.currentTimeMillis();
long n2 = System.nanoTime();
a number of times until the difference between n1 and n2 is less than the resolution you want (it's about 400 ns on my PC after a couple of iterations).
You can then use the difference between n1 (or n2 or an average of the 2...) and m * 1e6 as an offset that you need to add to System.nanoTime() to get the current epoch nanos.
Disclaimer:
System.nanoTime doc explicitly states that the resolution is at least that of System.currentTimeMillis(), which may be > 1 ms. So no guarantee that you will get microsecond resolution.
Corollary: this probably doesn't work in all environments (you may never get n2-n1 small enough - or it may be 0 just because the resolution of your system is too low).
System.nanoTime() may be out of sync over long periods - so this is a trade off between precision and performance.
You also need to account for possible arithmetic overflow.
See also: Current time in microseconds in java

Can I use nanoTime instead of randomUUID?

I am writing a process that returns data to a subscribers every few seconds. I would like to create a unique id for to the subscribers:
producer -> subsriber1
-> subsriber2
What is the difference between using:
java.util.UUID.randomUUID()
System.nanoTime()
System.currentTimeMillis()
Will the nano time always be unique? What about the random UUID?
UUID
The 128-bit UUID was invented exactly for your purpose: Generating identifiers across one or more machines without coordinating through a central authority.
Ideally you would use the original Version 1 UUID, or its variations in Versions 2, 3, and 5. The original takes the MAC address of the host computer’s network interface and combines it with the current moment plus a small arbitrary number that increments when the host clock has been adjusted. This approach eliminates any practical concern for duplicates.
Java does not bundle an implementation for generating these Versions. I presume the Java designers had privacy and security concerns over divulging place, time, and MAC address.
Java comes with only one implementation of a generator, for Version 4. In this type all but 6 of the 128 bits are randomly generated. If a cryptographically strong random generator is used, this Version is good enough to use in most common situations without concern for collisions.
Understand that 122 bits is a really big range of numbers (5.316911983139664e+36). 64-bits yields a range of 18,446,744,073,709,552,000 (18 quintillion). The remaining 58 bits (122-64=58) yields a number range of 288,230,376,151,711,740 (288 quadrillion). Now multiply those two numbers to get the range of 122-bits: 2^122 = ( 18,446,744,073,709,552,000 * 288,230,376,151,711,740 ) which is 5.3 undecillion.
Nevertheless, if you have access to generating a Version of UUID other than 4, take it. For example in a database system such as Postgres, the database server can generate UUID numbers in the various Versions including Version 1. Or you may find a Java library for generating such UUIDs, though that library may not be platform-independent (it may have native code within).
System.nanoTime
Be clear that System.nanoTime has nothing to do with the current date and time. To quote the 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.
The System.nanoTime feature simply returns a long number, a count of nanoseconds since some origin, but that origin is not specified.
The only promise made in the Java spec is that the origin will not change during the runtime of a JVM. So you know the number is ever increasing during execution of your app. Unless reaching the limit of a long, when the counter will rollover. That rollover might take 292 years (2^63 nanoseconds), if the origin is zero — but, again, the origin is not specified.
In my experience with the particular Java implementations I have used, the origin is the moment when the JVM starts up. This means I will most certainly see the same numbers all over again after the next JVM restart.
So using System.nanoTime as an identifier is a poor choice. Whether your app happens to hit coincidentally the exact same nanosecond number as seen in a prior run is pure chance, but a chance you need not take. Use UUID instead.
java.util.UUID.randomUUID() is potentially thread-safe.
It is not safe to compare the results of System.nanoTime() calls between different threads. If many threads run during the same millisecond, this function returns the same milliseconds.
The same is true for System.currentTimeMillis() also.
Comparing System.currentTimeMillis() and System.nanoTime(), the latter is more expensive as it takes more cpu cycles but is more accurate too. So UUID should serve your purpose.
I think yes, you can use System.nanoTime() as id. I have tested it and did not face with duplication.
P.S. But I strongly offer you to use UUID.

Precise metronome for android

The answer to this question states that we can make a reliable and precise metronome on Android using AudioTrack. We can use MediaPlayer, SoundPool, Thread and Timer as well, but they are always causing a delay. Instead of generating a synthesized sound using AudioTrack, how can we achieve the same effect using custom audio files?
You can try to create your own time counter using System.nanoTime(), when you need precision, you always can use this.
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 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;
Returns: The current value of the system timer, in nanoseconds. Since:
1.5
Source:
Oracle Documentation https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime()

Is there an infinite Duration in Java 8 equivalent to the .NET Timeout.InfiniteTimeSpan Field?

Everything is in the title:
Is there an infinite Duration in Java 8 equivalent to the C# Timeout.InfiniteTimeSpan Field?
A bit like:
https://msdn.microsoft.com/en-us/library/system.threading.timeout.infinitetimespan(v=vs.110).aspx
I don't think -1 ms is understood across the all java libraries as an infinite timespan, so it might be more a problem of definition.
In order to clarify a bit the context, let's say I want to make a thread asleep for an infinite amount of time without performing an infinite loop, note that this not necessarily a realistic practical use though.
I'm just wondering is there anything built-in in the Java libraries?
As an extension to #Misha's answer, this is essentially the largest duration value allowed:
public static final Duration MAX_DURATION = Duration.ofSeconds(
Long.MAX_VALUE, // Max allowed seconds
999999999L // Max nanoseconds less than a second
);
Anything more than this leads to
java.lang.ArithmeticException: long overflow
From Duration javadoc:
A physical duration could be of infinite length. For practicality, the duration is stored with constraints similar to Instant. The duration uses nanosecond resolution with a maximum value of the seconds that can be held in a long. This is greater than the current estimated age of the universe.
You certainly don't need to do an infinite loop to suspend a thread. Consider LockSupport.park() or another one of the many available mechanisms in java.util.concurrent. Can you describe your problem in more detail?

Java System.nanoTime() huge difference in elapsed time

I'm in and android widget and checking elapsed time between two calls of System.nanoTime() and the number is huge. How do you measure elapsed time with this? it should be a fraaction of a second and instead its much more. Thanks
The System.nanoTime() returns a time value whose granularity is a nanosecond; i.e. 10-9 seconds, as described in the javadoc. The difference between two calls to System.nanoTime() that are a substantial fraction of a second apart is bound to be a large number.
If you want a time measure with a larger granularity, consider System.currentTimeMillis() ... or just divide the nanosecond values by an appropriate power of 10 to suit your application.
Note that on the Android platform there are 3 distinct system clocks that support different "measures" of time; see SystemClock. If you are programming explicitly for the Android platform, you should read the javadoc and decide which measure is most appropriate to what you are doing.
For your information, "nano-" is one of the standard prefixes defines by the International System of Units (SI) - see http://physics.nist.gov/cuu/Units/prefixes.html.
If you really think that "they" got it wrong and that "nano-" is too small, you could always write a letter to the NIST. I'm sure someone would appreciate it ... :-)
One seconds contains 1,000,000,000 nanoseconds, so as long as your number is in that range, it's reasonable.
If you want it in fractional form, just take your value / 10^9 where value is your difference in nanoTime()s.
long nanoSeconds = 500000000;
float seconds = nanoSeconds / 1000000000;
Log.i("NanoTime", nanoSeconds + " ns is the same as " + seconds + " seconds");
Your output would be:
07-27 11:35:47.196: INFO/NanoTime(14237): 500000000 ns is the same as 0.5 seconds

Categories

Resources