Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vladimirdolzhenko/4b3f46124ce1428e1efc5e4b44acbc21 to your computer and use it in GitHub Desktop.
Save vladimirdolzhenko/4b3f46124ce1428e1efc5e4b44acbc21 to your computer and use it in GitHub Desktop.

9049090

There is an issue in SystemClock in java 9:

With JDK-8068730 SystemClock uses more precise timestamp provider, but it uses incorrect timeprovider for Windows - GetSystemTimeAsFileTime - see commit - that provides similar resolution as System.currentTimeMillis.

There is another timeprovider in WinAPI that gives wall-clock time with higher resolution - GetSystemTimePreciseAsFileTime

Simple show-case:

import java.time.Clock;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;

/**
 * @author vladimir.dolzhenko
 * @since 2017-05-12
 */
public class ClockTest {
    public static void main(String[] args) {
        final Clock clock = Clock.systemUTC();

        int count = 10;
        Instant[] instants = new Instant[count];
        final long start = System.nanoTime();
        for (int i = 0; i < count; i++) {
            instants[i] = clock.instant();
        }
        final long end = System.nanoTime();

        System.out.println("java.version:" + System.getProperty("java.version"));
        System.out.println("took " + (end - start) / 1e3 + " us");
        System.out.println("clock diff " + ChronoUnit.MICROS.between(instants[0], instants[count - 1]) + " us");
        long[] diffs = new long[count - 1];
        for (int i = 1; i < count; i++) {
            diffs[i - 1] = ChronoUnit.MICROS.between(instants[i - 1], instants[i]);
        }
        System.out.println("instants " + Arrays.toString(instants) + " us");
        System.out.println("diffs " + Arrays.toString(diffs) + " us");

    }
}

Results on Windows:

java.version:9-ea
took 68.991 us
clock diff 0 us
instants [2017-05-12T11:28:36.489481500Z, 2017-05-12T11:28:36.489481500Z, 2017-05-12T11:28:36.489481500Z, 2017-05-12T11:28:36.489481500Z, 2017-05-12T11:28:36.489481500Z, 2017-05-12T11:28:36.489481500Z, 2017-05-12T11:28:36.489481500Z, 2017-05-12T11:28:36.489481500Z, 2017-05-12T11:28:36.489481500Z, 2017-05-12T11:28:36.489481500Z] us
diffs [0, 0, 0, 0, 0, 0, 0, 0, 0] us

Results on Linux:

 $  ~/jdk9/bin/java ClockTest
java.version:9-ea
took 150.142 us
clock diff 135 us
instants [2017-05-12T10:49:05.227999Z, 2017-05-12T10:49:05.228126Z, 2017-05-12T10:49:05.228127Z, 2017-05-12T10:49:05.228129Z, 2017-05-12T10:49:05.228130Z, 2017-05-12T10:49:05.228131Z, 2017-05-12T10:49:05.228132Z, 2017-05-12T10:49:05.228132Z, 2017-05-12T10:49:05.228133Z, 2017-05-12T10:49:05.228134Z] us
diffs [127, 1, 2, 1, 1, 1, 0, 1, 1] us

Or in terms of granularity (see Granularity benchmark and result details )

java 9:

OS             Value          Units
MacOSX:     1011.522          ns/op
Windows:  999916.218          ns/op
Linux:      1002.419          ns/op

There is a similar issue for .NET CLR: Use GetSystemTimePreciseAsFileTime for DateTime.UtcNow

Credits to wizzard0 (warning: post regarding SystemUTC in java 9 in Russian)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment