リフレクションって、どれくらい遅くなるの?
「リフレクションを大量に使うときはキャッシュせよ!」とは良く聞きますが、「キャッシュしたからと言って、速いのか?」という疑問がありました。そこで、検証。リフレクションと、直接のメソッド呼び出しを10億回実行して時間を比較してみました。
メインプログラムは以下の通り。単にsetterを呼び出しているだけです。
package jp.gr.java_conf.snuffkin.sandbox.reflection; import java.lang.reflect.Method; public class TestReflectionSpeed { public static void main(String[] args) throws Exception { SampleEntity target = new SampleEntity(); Method method = SampleEntity.class.getMethod("setName", String.class); int call = 1000000000; 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)); } }
呼び出しているエンティティクラスは以下の通り。
package jp.gr.java_conf.snuffkin.sandbox.reflection; public class SampleEntity { private String name; public void setName(String name) { this.name = name; } }
私が測定に使ったのは、Core2DuoのMac Book Air。いまどきのマシンと比べるとCPU性能は落ちますね。で、結果は以下の通り。
reflection :time(ms)=19054 direct call:time(ms)=44
確かに、直接メソッドを読んだ方が速いです。しかし、10億回をリフレクションを呼んでも19秒。この性能なら、大抵のアプリケーションでリフレクションを使っても性能的に問題なさそうですね。