• Apache、Spring、Cglib的beancopy效率对比


    关于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的实现方法,由此提高效率。

  • 相关阅读:
    Navicat连接MySQL数据库的一些问题与解决方案
    从select机制谈到epoll机制
    关于VS2017提示I/O文件操作函数需要加上_s的解决办法
    LeetCode初级算法(树篇)
    LeetCode初级算法(动态规划+设计问题篇)
    LeetCode初级算法(其他篇)
    Leetcode初级算法(排序和搜索+数学篇)
    Leetcode初级算法(链表篇)
    Leetcode初级算法(字符串篇)
    机器学习之k-近邻算法
  • 原文地址:https://www.cnblogs.com/liesun/p/11737122.html
Copyright © 2020-2023  润新知