Indyが早くないので、教えてください!
会社の同僚が、リフレクションと普通のメソッド呼び出しについて、
簡単なベンチマークを取って比較していました。
で、結果は以下の通り。
リフレクションって、どれくらい遅くなるの? - snuffkinの遊び場
reflection :time(ms)=19054
direct call:time(ms)=44
これを見て、「イマドキなら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は用途が違うんだよと言われれば、それまでの話なんですけどね・・・