谷本 心 in せろ部屋

はてなダイアリーから引っ越してきました

Indyが早くないので、教えてください!

会社の同僚が、リフレクションと普通のメソッド呼び出しについて、
簡単なベンチマークを取って比較していました。

で、結果は以下の通り。
reflection :time(ms)=19054
direct call:time(ms)=44

リフレクションって、どれくらい遅くなるの? - snuffkinの遊び場

これを見て、「イマドキならIndy(InvokeDynamic)使った方が早いんじゃん?」とかって
調子に乗ってコードを書いてみたのですが、ちっとも早くなりませんでした。


私の環境で、1億回ループさせたところ、

直接呼び出し : 10ms程度
リフレクション : 700ms程度
Indy : 6000ms程度

という感じで、ベンチマークの稚拙さに目をつぶったとしても、明らかにIndyが遅い結果になりました。


きっと書き方が悪いか、リフレクションにとって有利すぎるベンチマークになっているのだと思いますが、
有識者の方にアドバイスを頂ければありがたいです m(_ _)m


ベンチマーククラス

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;

public class TestIndySpeed {
	public static void main(String[] args) throws Throwable {
		SampleEntity target = new SampleEntity();
		Method method = SampleEntity.class.getMethod("setName", String.class);

		Lookup lookup = MethodHandles.lookup();
		MethodHandle setName = lookup.findVirtual(SampleEntity.class,
				"setName", MethodType.methodType(void.class, String.class));

		int call = 100 * 1000 * 1000;
		for (int i = 0; i < 3; i++) {
			long startTime = System.currentTimeMillis();
			for (int index = 0; index < call; index++) {
				method.invoke(target, "test");
			}
			System.out.println("reflection :time(ms)="
					+ (System.currentTimeMillis() - startTime));

			startTime = System.currentTimeMillis();
			for (int index = 0; index < call; index++) {
				target.setName("test");
			}
			System.out.println("direct call:time(ms)="
					+ (System.currentTimeMillis() - startTime));

			startTime = System.currentTimeMillis();
			for (int index = 0; index < call; index++) {
				setName.invokeWithArguments(target, "test");
			}
			System.out.println("dynamic call:time(ms)="
					+ (System.currentTimeMillis() - startTime));
		}
	}
}


呼び出し対象クラス

public class SampleEntity {
	public String name;
	public void setName(String name) {
        this.name = name;
    }
}

こんな感じで、シンプルな処理を呼び出しているだけです。


いや、Indyは用途が違うんだよと言われれば、それまでの話なんですけどね・・・