首页 > 编程语言 > 详细

Apache、Spring、Cglib的beancopy效率对比

时间:2019-10-25 12:28:41      阅读:82      评论:0      收藏:0      [点我收藏+]

关于BeanCopy

在项目中发现在对一个对象进行拷贝赋值的时候都在使用BeanFactory类的beanCopy()方法,该方法可方便地复制属性值,节省了大量的get、set操作,其实现如下所示:

public class BeanFactory {
    public static <T> T beanCopy(T t, Object orig){
        try {
            BeanUtils.copyProperties(t,orig);
        }catch (Exception e){
            throw new RuntimeException("复制对象属性出错",e);
        }
        return  t;
    }
}

copyProperties()方法在apache提供的一个工具类BeanUtils中定义。
但是,IDE提示说该方法效率低下,推荐使用其他的方法,提示如下:

避免用Apache Beanutils进行属性的copy 说明:Apache BeanUtils 性能较差 ,可以使用其他方案比如Spring BeanUtils, Cglib BeanCopier

  TestObject a = new TestObject();
  TestObject b = new TestObject();
  a.setX(b.getX());
  a.setY(b.getY());

为此,分别使用Apache BeanUtilsSpring BeanUtilscglib BeanCopier,以及JSON的方式进行beancopy操作,对其效率作对比,其拷贝方式如下:

public class BeanFactory {
    
    //Apache copy
    public static <T> T beanCopy(T t, Object orig){
        try {
            BeanUtils.copyProperties(t,orig);
        }catch (Exception e){
            throw new RuntimeException("Apache BeanUtils复制对象属性出错",e);
        }
        return  t;
    }
    
    //Spring copy
    public static <T> T copybean(T t, Object orig){
        try{
            org.springframework.beans.BeanUtils.copyProperties(orig,t);
        }catch (Exception e){
            throw new RuntimeException("Spring BeanUtils复制对象属性出错",e);
        }
        return t;
    }

    //cglib copy
    public static <T> T cglibcopy(T t,Object orig,Class clazz){
        try {
            final BeanCopier beanCopier = BeanCopier.create(clazz,clazz,false);
            beanCopier.copy(orig,t,null);

        }catch (Exception e){
            throw new RuntimeException("cglib BeanCopier复制对象属性出错",e);
        }
        return t;
    }

    //json copy
    public static Object jsonCopy(Object orgi,Class clazz){
        try{
            String json = JSON.toJSONString(orgi);
            return JSON.parseObject(json,clazz);

        }catch (Exception e){
            throw new RuntimeException("json parse复制对象属性出错",e);
        }
    }
}

首先进行10000次拷贝测试,其结果如下:
| | Apache | Spring | cglib | JSON |
| ---- | ------ | ------ | ----- | ---- |
| 1 | 1663 | 271 | 159 | 244 |
| 2 | 1696 | 130 | 186 | 243 |
| 3 | 1798 | 136 | 186 | 138 |
| Avg | 1719 | 179 | 177 | 208.3|

然后进行100次拷贝测试:
| | Apache | Spring | cglib | JSON |
| ---- | ------ | ------ | ----- | ---- |
| 1 | 227 | 77 | 84 | 137 |
| 2 | 270 | 83 | 83 | 142 |
| 3 | 257 | 99 | 84 | 150 |
| Avg | 251.3 | 86.3 | 83.6 | 143|
最后是10次拷贝测试:
| | Apache | Spring | cglib | JSON |
| ---- | ------ | ------ | ----- | ---- |
| 1 | 186 | 69 | 81 | 137 |
| 2 | 184 | 70 | 86 | 131 |
| 3 | 183 | 71 | 84 | 119 |
| Avg | 184.3 | 70 | 83.6 |129 |
可以看出,不论拷贝次数的多少,Apache的效率总是最差的,而Springcglib(不使用缓存)效率相当,JSON的效率比Apache稍好,但是与Springcglib还有一定的差距。整体而言,效率由高到低的排序为:

getter/setter > cglib > Spring > Apache

在使用cglib进行测试的的时候,遇到java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter overrides final method visit.(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V的报错信息,其原因是asm高版本的jar包与cglib:2.2jar包存在冲突,将asm版本降级到3.x可解决该问题。

结合项目中asm高版本的jar包使用较多的实际情况,建议以后使用 Spring BeanUtils 方法作为BeanCopy的实现方法,由此提高效率。

Apache、Spring、Cglib的beancopy效率对比

原文:https://www.cnblogs.com/liesun/p/11737122.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!