直接呼出しとリフレクション。
ふと思い立って、コードを書いてみたり。
結局どれだけ差があるのさ?
- 結果。
CGLib TOTAL : 172,212,794 CGLib AVG : 172 Reflection TOTAL : 404,496,857 Reflection AVG : 404 Direct TOTAL : 97,788,141 Direct AVG : 97 ================== CGLib TOTAL : 149,866,977 CGLib AVG : 149 Reflection TOTAL : 396,531,053 Reflection AVG : 396 Direct TOTAL : 95,978,462 Direct AVG : 95 ================== CGLib TOTAL : 142,808,269 CGLib AVG : 142 Reflection TOTAL : 399,944,598 Reflection AVG : 399 Direct TOTAL : 95,536,951 Direct AVG : 95 ================== CGLib TOTAL : 146,544,536 CGLib AVG : 146 Reflection TOTAL : 402,051,285 Reflection AVG : 402 Direct TOTAL : 97,291,030 Direct AVG : 97 ================== CGLib TOTAL : 147,852,179 CGLib AVG : 147 Reflection TOTAL : 396,690,007 Reflection AVG : 396 Direct TOTAL : 95,101,145 Direct AVG : 95 ==================
つまり、直接呼出しが、4倍程度速い感じ。
単に比較の問題なので、別に速いからどうと言う事も無いけれど。
CGLibのFastClassも意外と速いけど、直接呼出しに比べると遅いらしい。
- 思い立ったテストコード。
public class Main { public static void main(String[] args) { for (int i = 0; i < 5; i++) { test(); System.out.println("=================="); } } public static void test() { try { String instance = "aabbccddeeddffgghhjjkkllmmnn"; Test[] tests = new Test[] { new CGLib(), new Reflection(), new Direct() }; int count = 1000000; for (int i = 0; i < tests.length; i++) { Test test = tests[i]; test.init(); long start = System.nanoTime(); for (int j = 0; j < count; j++) { test.invoke(instance); } long total = System.nanoTime() - start; System.out.printf("%1$-10s TOTAL : %2$,15d%n", test.name(), total); if (0 < total) { System.out.printf("%1$-10s AVG : %2$,15d%n", test.name(), total / count); } else { System.out.println(test.name() + " AVG : (too fast)"); } } } catch (Exception e) { e.printStackTrace(); } } interface Test { String name(); void init() throws Exception; void invoke(String instance) throws Exception; } static class Reflection implements Test { Method m = null; public String name() { return "Reflection"; } public void init() throws Exception { m = String.class.getMethod("indexOf", new Class[] { String.class }); } public void invoke(String instance) throws Exception { m.invoke(instance, new Object[] { "ll" }); } } static class Direct implements Test { public String name() { return "Direct"; } public void init() throws Exception { } public void invoke(String instance) throws Exception { instance.indexOf("ll"); } } static class CGLib implements Test { FastClass clazz; int index; public String name() { return "CGLib"; } public void init() throws Exception { clazz = FastClass.create(String.class); index = clazz.getIndex("indexOf", new Class[] { String.class }); } public void invoke(String instance) throws Exception { clazz.invoke(index, instance, new Object[] { "ll" }); } } }
虎が使えてねぇぞ。ゴルァと突っ込まれましたので、綺麗に見える様にしてみるました。
コードのインデントを変えてみるました。