转载

Bean复制的几种框架性能比较(Apache BeanUtils、PropertyUtils,Spring BeanUtils,Cglib BeanCopier)

       
public class FromBean {
   private String name;
   private int age;
   private String address;
   private String idno;
   private double money;
   public double getMoney() {
     return money;
   }
   public void setMoney( double money) {
     this .money = money;
   }
   public String getName() {
     return name;
   }
   public void setName(String name) {
     this .name = name;
   }
   public int getAge() {
     return age;
   }
   public void setAge( int age) {
     this .age = age;
   }
   public String getAddress() {
     return address;
   }
   public void setAddress(String address) {
     this .address = address;
   }
   public String getIdno() {
     return idno;
   }
   public void setIdno(String idno) {
     this .idno = idno;
   }
}

一个用于测试的BenchmarkTest类,为了减少重复代码,写了一个策略模式

public class BenchmarkTest {
    private int count;

    public BenchmarkTest(int count) {
        this.count = count;
        System.out.println("性能测试" + this.count + "==================");
    }

    public void benchmark(IMethodCallBack m, FromBean frombean) {
        try {
            long begin = new java.util.Date().getTime();
            ToBean tobean = null;
            System.out.println(m.getMethodName() + "开始进行测试");
            for (int i = 0; i < count; i++) {

                tobean = m.callMethod(frombean);

            }
            long end = new java.util.Date().getTime();
            System.out.println(m.getMethodName() + "耗时" + (end - begin));
            System.out.println(tobean.getAddress());
            System.out.println(tobean.getAge());
            System.out.println(tobean.getIdno());
            System.out.println(tobean.getMoney());
            System.out.println(tobean.getName());
            System.out.println("                                      ");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

策略中使用的接口声明

public interface IMethodCallBack {

String getMethodName();

ToBean callMethod(FromBean frombean)   throws Exception;

}

使用的测试类

public   class  TestMain {

/**
@param

args

*/

public   static   void  main(String[] args) {

FromBean fb =  new  FromBean();

fb.setAddress("北京市朝阳区大屯路");

fb.setAge(20);

fb.setMoney(30000.111);

fb.setIdno("110330219879208733");

fb.setName("测试");

IMethodCallBack beanutilCB =  new  IMethodCallBack() {

@Override

public  String getMethodName() {

return  "BeanUtil.copyProperties";

}

@Override

public  ToBean callMethod(FromBean frombean)  throws  Exception {

ToBean toBean =  new  ToBean();

BeanUtils.copyProperties(toBean, frombean);

return  toBean;

}

};

IMethodCallBack propertyCB =  new  IMethodCallBack() {

@Override

public  String getMethodName() {

return  "PropertyUtils.copyProperties";

}

@Override

public  ToBean callMethod(FromBean frombean)  throws  Exception {

ToBean toBean =  new  ToBean();

PropertyUtils.copyProperties(toBean, frombean);

return  toBean;

}

};

IMethodCallBack springCB =  new  IMethodCallBack() {

@Override

public  String getMethodName() {

return  "org.springframework.beans.BeanUtils.copyProperties";

}

@Override

public  ToBean callMethod(FromBean frombean)  throws  Exception {

ToBean toBean =  new  ToBean();

org.springframework.beans.BeanUtils.copyProperties(frombean,

toBean);

return  toBean;

}

};

IMethodCallBack cglibCB =  new  IMethodCallBack() {

BeanCopier bc = BeanCopier.create(FromBean. class , ToBean. class ,

false );

@Override

public  String getMethodName() {

return  "BeanCopier.create";

}

@Override

public  ToBean callMethod(FromBean frombean)  throws  Exception {

ToBean toBean =  new  ToBean();

bc.copy(frombean, toBean,  null );

return  toBean;

}

};

//另外一种BeanCopier缓存实现,效率更高

IMethodCallBack cglibCB2 =  new  IMethodCallBack() {

private ConcurrentHashMap<String,BeanCopier> cache=new ConcurrentHashMap<String, BeanCopier>();

@Override

public  String getMethodName() {

return  "BeanCopier.create";

}

@Override

public  ToBean callMethod(FromBean frombean)  throws  Exception {

ToBean toBean =  new  ToBean();

return copyBeanProperties(sourceObj, target, false);

}

if(sourceObj==null||target==null) return null;

String key=sourceObj.getClass().getSimpleName()+target.getClass().getSimpleName();

BeanCopier copier = cache.get(key);

if(copier==null){

copier=createBeanCopier(sourceObj.getClass(), target.getClass(), useConverter, key);

}

copier.copy(sourceObj, target, null);

return target;

}

@SuppressWarnings({"rawtypes" })

private  BeanCopier createBeanCopier(Class sourceClass,Class targetClass,boolean useConverter,String cacheKey){

BeanCopier copier = BeanCopier.create(sourceClass,targetClass, useConverter);

cache.putIfAbsent(cacheKey, copier);

return copier;

}  

};

//  数量较少的时候,测试性能
        BenchmarkTest bt =  new  BenchmarkTest(10);

bt.benchmark(beanutilCB, fb);

bt.benchmark(propertyCB, fb);

bt.benchmark(springCB, fb);

bt.benchmark(cglibCB, fb);

//  测试一万次性能测试
        BenchmarkTest bt10000 =  new  BenchmarkTest(10000);

bt10000.benchmark(beanutilCB, fb);

bt10000.benchmark(propertyCB, fb);

bt10000.benchmark(springCB, fb);

bt10000.benchmark(cglibCB, fb);

//  担心因为顺序问题影响测试结果
        BenchmarkTest bt1000R =  new  BenchmarkTest(10000);

bt1000R.benchmark(cglibCB, fb);

bt1000R.benchmark(springCB, fb);

bt1000R.benchmark(propertyCB, fb);

bt1000R.benchmark(beanutilCB, fb);

}

}

进行了三次测试,最后的结果如下:

10次测验 第一次 第二次 第三次 平均值 每次平均值
BeanUtil.copyProperties 54 57 50 53.66667 5.366666667
PropertyUtils.copyProperties 4 4 4 4 0.4
org.springframework.beans.BeanUtils.copyProperties 12 10 11 11 1.1
BeanCopier.create 0 0 0 0 0
10000次测验 第一次 第二次 第三次 平均值 每次平均值
BeanUtil.copyProperties 241 222 226 229.6667 0.022966667
PropertyUtils.copyProperties 92 90 92 91.33333 0.009133333
org.springframework.beans.BeanUtils.copyProperties 29 30 32 30.33333 0.003033333
BeanCopier.create 1 1 1 1 0.1
10000次反转测验 第一次 第二次 第三次 平均值 每次平均值
BeanUtil.copyProperties 178 174 178 176.6667 0.017666667
PropertyUtils.copyProperties 91 87 89 89 0.0089
org.springframework.beans.BeanUtils.copyProperties 21 21 21 21 0.0021
BeanCopier.create 0 1 1 0.666667 6.66667E-05
原文  http://www.blogjava.net/jlin/archive/2017/07/25/432690.html
正文到此结束
Loading...