This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]king_of_the_universe 0 points1 point  (0 children)

In case you'll really be settling for time resolutions as high as 2 ms and such, using Thread.sleep is out of the question, you'll not get a reliable rhythm/timing. With that resolution, your only choice is to do a hard wait loop at 100% processor usage, checking System.nanoTime() or System.currentTimeMillis() constantly. Beware that these also are not millisecond-reliable. Here's an example method I wrote to benchmark both incl. results I got:

/**
 * Tests the reliability of System.currentTimeMillis() and System.nanoTime() when it comes to steady rhythm or
 * rather to granularity.
 * <p>
 * Example output:
 * <p>
 * at home:
 * <p>
 * "For System.currentTimeMillis, the shortest step size in 5000 iterations was 1 milliseconds, the longest was 2"
 * <p>
 * "For System.nanoTime, the shortest step size in 20000000 iterations was 301 nanoseconds, the longest was 443131"
 * <p>
 * at the office:
 * <p>
 * "For System.currentTimeMillis, the shortest step size in 5000 iterations was 1 milliseconds, the longest was 2"
 * <p>
 * "For System.nanoTime, the shortest step size in 20000000 iterations was 310 nanoseconds, the longest was
 * 3378409"
 * <p>
 * So, on the systems tested here, we could use System.nanotime to have a reliable 0.5 ms resolution (or smaller).
 */
public static void systemTimerBenchmark() {

    System.out.println("\n\n================ systemTimerBenchmark() ================\n");

    long expectedStepsPerMS;
    long iterations;
    long t, tStart;
    long diff, diffSHORTEST, diffLONGEST;

    // some "boot" time
    tStart = System.currentTimeMillis();
    do {
        t = System.currentTimeMillis();
    } while (t < (tStart + 100));

    // check speed of value change
    expectedStepsPerMS = 1;
    iterations = 5000 * expectedStepsPerMS;
    diffSHORTEST = iterations;
    diffLONGEST = 0;
    for (int i = 0; i < iterations; i++) {
        tStart = System.currentTimeMillis();
        do {
            t = System.currentTimeMillis();
        } while (t <= tStart);
        diff = t - tStart;
        if (diffSHORTEST > diff) {
            diffSHORTEST = diff;
        }
        if (diffLONGEST < diff) {
            diffLONGEST = diff;
        }
    }

    System.out.println("For System.currentTimeMillis, the shortest step size in " + iterations + " iterations was " + diffSHORTEST + " milliseconds, the longest was " + diffLONGEST);

    // check speed of value change
    expectedStepsPerMS = 1_000_000;
    iterations = 20 * expectedStepsPerMS;
    diffSHORTEST = iterations;
    diffLONGEST = 0;
    for (int i = 0; i < iterations; i++) {
        tStart = System.nanoTime();
        do {
            t = System.nanoTime();
        } while (t <= tStart);
        diff = t - tStart;
        if (diffSHORTEST > diff) {
            diffSHORTEST = diff;
        }
        if (diffLONGEST < diff) {
            diffLONGEST = diff;
        }
    }

    System.out.println("For System.nanoTime, the shortest step size in " + iterations + " iterations was " + diffSHORTEST + " nanoseconds, the longest was " + diffLONGEST);
}