I don't want to change this code, I'm only interested in JVM, OS or kernel customization/configuration for best results!
I have one second loop (1000 x 1ms)
public static void main(String[] args) throws InterruptedException {
long start = System.nanoTime();
for (int i = 0; i < 1000; i++ ) {
Thread.sleep(TimeUnit.MILLISECONDS.toMillis(1));
}
long duration = System.nanoTime() - start;
System.out.println("Loop duration " +
duration / TimeUnit.MILLISECONDS.toNanos(1) + " ms.");
}
On my Fedora 20 with kernel 3.12 this loop needs 1055 ms.
This is pretty good result, average is more than 1100ms.
Is possible to make this code faster with custom JVM flags or OS configuration?
Loop duration 1055 ms.
Calling
sleep()
you are basically telling the OS to suspend your thread for AT LEAST X milliseconds. There is no guarantee whatsoever that it will continue executing exactly after this time or the OS will re-scheadule your thread later. Furthermore, the minimum amount ofsleep
time and its accuracy heavily depends on the OS.EDIT: Also you should take into account that in your case , (most probably) your code is being interpreted! JAva compiles to native code only
hotspots
(and fromm here comes the name of the Hotspot JIT) which are being executed frequently. Forserver
VM, this is 10k executions of a given code. You only have 1k.System.currentTimeMillis
should not be used as a measure of elapsed time. You should be usingSystem.nanoTime
. Look here for a bit more explanation.Well, you could obviously factor out the TimeUnit conversion and save a few cycles. You could also count down rather than up; using a !=0 test is usually faster than comparing to other values.
You should also make sure the code is fully JITted (which can take several minutes of running it) before you take ANY measurements.
Generally, microbenchmarks are misleading in Java, and microoptimizing without knowing how much that code contributes to your runtime tends to be wasted effort in any case. Don't bother with this sort of exercise. Write the best code you can, give it lots of warm-up time on an assortment real data, then use a profiler to see where it's spending its time (also on real data). That will tell you where performance tuning will actually be productive. Then consider algorithmic improvements, which tend to yield the highest benefit. Profile again with the new code and see what is hot now. Repeat.
Remember, infinite improvement of something that accounts for 1% of runtime takes infinite effort but yields only 1% improvement. Put your effort where it makes a difference. And, especially in hotspot Javas where code continues to be optimized during execution but that optimization is not fully deterministic, don't trust a single execution to give you real performance numbers.
By my knowledge, one of the factors here is the kernel system tick time (I think it's 200 tps for desktops, 100 for servers, and 1000 forRT systems). This causes small delays which accumulate up to the 55 ms. Additionally, the
sleep
call will have some system overhead, which is hard to reduce by itself.Why don't you simply put it into one single sleep?
I you really want to do 1000 sleep commands I recommend this:
This will make sure you only wait if that makes currently sense!
Unfortunately, my question was misunderstood.
Realtime java is abandoned, so advice for using Realtime java is not valid.
After some researches this test has best results on some Windows machines.
On tested Windows 8.1 this tests prints exactly 1000ms.
Other results:
References