次のコードは、インターフェイスハンドラーからメソッドhandle(Object o)を100回呼び出すのにかかる時間を測定します(はい、品質の低いプロファイリングです)。
package test;
import java.util.LinkedList;
public class Test {
static int i = 0;
private interface Handler {
public void handle(Object o);
}
private static class SuperHandler implements Handler {
public void handle(Object o) { i += 1; }
}
private static class NoSuperHandler implements Handler {
public void handle(Object o) { i += 1; }
}
private static class LulSuperHandler implements Handler {
public void handle(Object o) { i += 1; }
}
private static class LilSuperHandler implements Handler {
public void handle(Object o) { i += 1; }
}
private static class LolSuperHandler implements Handler {
public void handle(Object o) { i += 1; }
}
private static class LalSuperHandler implements Handler {
public void handle(Object o) { i += 1; }
}
private static class LylSuperHandler implements Handler {
public void handle(Object o) { i += 1; }
}
private static class LzlSuperHandler implements Handler {
public void handle(Object o) { i += 1; }
}
public static void main(String[] args) {
LinkedList<Handler> ll = new LinkedList<Handler>();
for(int j = 0; j < 100; j++) {
if((j % 8) == 0) ll.add(new SuperHandler());
if((j % 8) == 1) ll.add(new NoSuperHandler());
if((j % 8) == 2) ll.add(new LulSuperHandler());
if((j % 8) == 3) ll.add(new LilSuperHandler());
if((j % 8) == 4) ll.add(new LolSuperHandler());
if((j % 8) == 5) ll.add(new LalSuperHandler());
if((j % 8) == 6) ll.add(new LylSuperHandler());
if((j % 8) == 7) ll.add(new LzlSuperHandler());
}
long begin = System.currentTimeMillis();
for(int j = 0; j < 1000000; j++) for(Handler h: ll) h.handle(null);
System.out.println("time in ms: " + (System.currentTimeMillis() - begin));
System.out.println("i: " + i);
}
}
事実、LinkedListに含まれるハンドラーの種類が1つだけの場合、たとえばSuperHandlerの場合、実行時間は、2、3などの異なる種類のハンドラーの場合よりも短くなります。また、リストに新しい種類のハンドラーを追加するたびに、パフォーマンスが低下します。
たとえば、この部分だけを変更すると、上記よりも優れたパフォーマンスが得られます。
for(int j = 0; j < 100; j++) {
if((j % 2) == 0) ll.add(new SuperHandler());
if((j % 2) == 1) ll.add(new NoSuperHandler());
}
ここで動作する特別な最適化はありますか?JAVAアーキテクチャでは、パフォーマンスはどのように低下しますか?未使用のハンドラーがコンパイラーによって「削除」または「非表示」になっているため、テストが間違っていますか?(私はLinuxUbuntuを使用しています-OracleのJAVA1.7)