cglib 的 beanMap 与 反射 的效率
程序员文章站
2022-06-05 20:37:43
...
一直在用cglib,突然想起来还没有测试过他的效率到底如何,所以稍微测试了一下
对于有11个成员变量的bean,一个是直接使用java的反射读取,另一个是使用cglib转换beanMap以后直接使用get读取。(详细结果见下表)
可以看出, cglib 的效率是 直接反射的3倍(字节码编程确实很厉害!)另外,cglib的beanMap在初次创建一个类的缓存时会耗费一定的时间(300ms),之后使用了缓存,再创建相同的bean就不再有多余的时间消耗了。
cglib | 反射 | cglib | 反射 | cglib | 反射 | |
循环10000次 | 100000 | 1000000 | ||||
时间(毫秒) | 344 | 156 | 719 | 1234 | 4203 | 11531 |
时间(毫秒) | 47 | 125 | 438 | 1218 | 3859 | 11391 |
时间(毫秒) | 31 | 125 | 407 | 1406 | 3781 | 11500 |
时间(毫秒) | 47 | 125 | 437 | 1250 | 3797 | 11484 |
时间(毫秒) | 47 | 125 | 407 | 1218 | 3781 | 11547 |
时间(毫秒) | 31 | 125 | 438 | 1219 | 3781 | 11469 |
时间(毫秒) | 31 | 125 | 421 | 1157 | 4438 | 11453 |
时间(毫秒) | 31 | 110 | 390 | 1172 | 3797 | 11406 |
时间(毫秒) | 47 | 125 | 406 | 1172 | 3797 | 11484 |
时间(毫秒) | 31 | 125 | 391 | 1156 | 3891 | 11609 |
时间(毫秒) | 47 | 125 | 391 | 1172 | 4172 | 11328 |
时间(毫秒) | 31 | 125 | 406 | 1234 | 3813 | 11343 |
时间(毫秒) | 31 | 125 | 407 | 1203 | 3813 | 11437 |
时间(毫秒) | 32 | 218 | 422 | 1203 | 3782 | 11797 |
时间(毫秒) | 78 | 235 | 438 | 1500 | 3953 | 11906 |
时间(毫秒) | 62 | 125 | 406 | 1922 | 4094 | 11515 |
时间(毫秒) | 47 | 125 | 469 | 1375 | 3844 | 11531 |
时间(毫秒) | 31 | 125 | 437 | 1266 | 3797 | 11766 |
时间(毫秒) | 47 | 110 | 437 | 1266 | 3781 | 11594 |
时间(毫秒) | 47 | 109 | 406 | 1344 | 3781 | 11453 |
总平均: | 57 | 134.4 | 434 | 1284 | 3898 | 11527.2 |
两者的速度比: | 0.424107143 | 0.33764161 | 0.33813502 | |||
除第一次平均: | 41.89 | 419 | 3882 | |||
初次多用时: | 302.1 | 300 | 321.3 |
public class CglibSpeedTest { int size = 1000000; List catchList = null; public List<SettleSubs> getInitData() { if (catchList != null ) { return catchList; } catchList = new ArrayList<SettleSubs>(size); for (int i = 0; i < size; i++) { SettleSubs settle = new SettleSubs();; settle.setBuyorsell ("s1s"); settle.setClientId ("s2s"); settle.setContractId ("s3s"); settle.setDayStr ("s4s"); settle.setDetailSeq (1 ); settle.setContractType("s5s"); settle.setCsgWarehouse("s6s"); settle.setDealPrice (2 ); settle.setSettlePrice (3 ); settle.setTotalQtt (4 ); settle.setRcptQtt (5 ); settle.setFrzCsgQtt (6 ); settle.setDepositAmt (7 ); settle.setSubsBalance (8 ); settle.setConveyQtt (9 ); settle.setCnyBalance (10 ); catchList.add(settle); } return catchList; } public long testReflectance() throws Exception { List<SettleSubs> list = getInitData(); // System.out.println("开始" + DateUtil.format(new Date())); long start = System.currentTimeMillis(); Class clazz = SettleSubs.class; List<Method> listMethods = new ArrayList<Method>(); for (Method method : clazz.getMethods()) { if (method.getName().startsWith("get")) { listMethods.add(method); } } for (SettleSubs settle: list) { // StringBuilder sb = new StringBuilder(); for (Method method : listMethods) { method.invoke(settle); } // System.out.println(sb); } // System.out.println(System.currentTimeMillis() - start); // System.out.println("完成:" + DateUtil.format(new Date())); return System.currentTimeMillis() - start; } public long testCglib() throws Exception { List<SettleSubs> list = getInitData(); // System.out.println("开始" + DateUtil.format(new Date())); long start = System.currentTimeMillis(); Set keyset = BeanMap.create(list.get(0)).keySet(); for (SettleSubs settle: list) { BeanMap map = BeanMap.create(settle); for (Object key : keyset) { map.get(key); } } // System.out.println(System.currentTimeMillis() - start); // System.out.println("完成:" + DateUtil.format(new Date())); return System.currentTimeMillis() - start; } public static void main(String[] args) throws Exception { // new CglibSpeedTest().testReflectance(); CglibSpeedTest test = new CglibSpeedTest(); System.out.println("次数:" + test.size); for (int i = 0; i < 20; i++) { System.out.println(test.testCglib() + "\t" + test.testReflectance()); } } }