一直在用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());
}
}
}