Are static block interpreted or does the JIT play a part?
When are methods optimized?
A method will be optimized when it is called often enough. This is controlled by the -XX:CompileThreshold=10000flag. The compilation occurs in the background by default and a short time later, the optimized version of the code will be used. (This is why it doesn’t always happen at exact the 10K mark)
However, loops can also be optimized if they are called often enough. This typically takes about 2-5 seconds. This is why any bound loop which does nothing takes about 2-5 seconds. (This is how long it takes the JIT to realize the loop doesn’t do anything)
However, loops can also be optimized if they are called often enough. This typically takes about 2-5 seconds. This is why any bound loop which does nothing takes about 2-5 seconds. (This is how long it takes the JIT to realize the loop doesn’t do anything)
How does this apply to static blocks?
Static block are never called more than once. Even if they are loaded by different class loaders, they are optimized independently. (In the unlikely event you loaded the same class 10,000 times, it still wouldn't be optimized)
However, it is quite possible to have a loop iterate many times in a static block (though rare) this can result in the static block begin optimized by the JIT.
However, it is quite possible to have a loop iterate many times in a static block (though rare) this can result in the static block begin optimized by the JIT.
public class Main {
static {
long start = System.nanoTime();
for (int i = 0; i < 5000; i++) ;
long time = System.nanoTime() - start;
System.out.printf("Took %.3f ms to iterate 5 thousand times%n", time / 1e6);
long start1 = System.nanoTime();
for (int i = 0; i < 5000; i++) ;
long time1 = System.nanoTime() - start1;
System.out.printf("Took %.3f ms to iterate 5 thousand times%n", time1 / 1e6);
long start2 = System.nanoTime();
for (int j = 0; j < 1000 * 1000; j++)
for (int i = 0; i < 1000 * 1000; i++) ;
long time2 = System.nanoTime() - start2;
System.out.printf("Took %.3f ms to iterate 1 trillion times%n", time2 / 1e6);
long start3 = System.nanoTime();
for (int j = 0; j < 1000 * 1000; j++)
for (int i = 0; i < 1000 * 1000; i++) ;
long time3 = System.nanoTime() - start3;
System.out.printf("Took %.3f ms to iterate 1 trillion times%n", time3 / 1e6);
}
public static void main(String[] args) {
}
}
run it with -XX:+PrintCompilation flag outputs.
64 1 java.lang.String::charAt (33 bytes)
75 2 java.lang.String::hashCode (64 bytes)
Took 0.067 ms to iterate 5 thousand times
Took 0.062 ms to iterate 5 thousand times
88 1% Main:: @ 124 (249 bytes)
Took 4.860 ms to iterate 1 trillion times
Took 0.001 ms to iterate 1 trillion times
You can see that a loop of 5,000 is not enough to trigger optimization, but a much larger loop does trigger optimization. Without the JIT, there is no way the loop of one trillion times would finish in 3 seconds.
Once the method has been optimize the last one trillion loop takes practically no time at all.
Once the method has been optimize the last one trillion loop takes practically no time at all.
No comments:
Post a Comment