一直在用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());
}
}
}
分享到:
相关推荐
五、反射与动态代理 1. 反射:Class类的使用,通过反射创建对象,调用方法和访问字段。 2. 动态代理:JDK动态代理和CGLIB动态代理的原理和应用。 六、Java虚拟机(JVM) 1. 类加载机制:双亲委派模型,加载、验证、...
- List、Set、Queue和Map接口的理解与实现类的使用。 - ArrayList、LinkedList、HashSet、HashMap的工作原理及性能比较。 - ConcurrentHashMap在并发环境中的应用。 3. **多线程与并发**: - 线程的创建方式:...
- `hibernate.cglib.use_reflection_optimizer`: 是否使用反射优化,默认为 `true`。 - `hibernate.cache.provider_class`: 缓存提供者,本例中为无缓存提供者。 此外,还需要通过 `<ref>` 引用之前定义的数据源 ...
1. List、Set与Map:熟练使用ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等容器。 2. 泛型:理解泛型的基本用法,以及类型擦除的概念。 3. 集合操作:掌握迭代器、增删改查操作,以及集合的排序与...
- **集合注入**:除了基本类型和简单对象之外,Spring 还支持向 Bean 注入集合类型(如 List、Set、Map 等)。 - **配置示例**:例如,可以在配置文件中定义一个包含多个元素的 List 并将其注入到 Bean 中。 ##### ...
Spring框架的加载流程包括Bean的加载和初始化,AOP的实现基于动态代理或CGLIB,事务管理支持多种传播属性和隔离级别。 通过这份面试题总览,可以系统地复习和掌握Java开发中的多个关键知识点,为面试或工作中遇到的...
StringBuffer和StringBuilder是可变的,线程安全与非安全,StringBuilder在单线程环境下比StringBuffer效率更高。 4. ArrayList和LinkedList都是List接口的实现。ArrayList基于动态数组,查询快,插入删除慢;...
- **Map**:HashMap, TreeMap, LinkedHashMap的区别和应用场景。 - **泛型**:理解泛型的约束、通配符和类型擦除。 4. **IO流** - **字节流与字符流**:InputStream/OutputStream和Reader/Writer的区别。 - **...
- **类型**:包括JDK动态代理(实现接口)和CGLIB动态代理(子类继承)。 ### 设计模式 - **单例模式**:确保一个类只有一个实例,并提供一个全局访问点。 - **工厂模式**:提供创建一系列相关或相互依赖对象的...