隨筆 - 100  文章 - 50  trackbacks - 0
          <2017年7月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          我收藏的一些文章!

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          作為一個新員工,一個首要的工作就是閱讀別人的代碼,閱讀代碼的諸多好處就不說了,我就直奔主題,通過預讀代碼,發現了幾種實現兩個不同類型的Bean之間實現值復制的幾種方式,上網查詢后發現性能上會有差異,于是就萌生自己深入了解幾種實現的想法。第一步就是先本著實事求是的原則去探求一下大家總結出來的性能差異是否正確。

           
                 比較的是四種復制的方式,分別為Apache的BeanUtils和PropertyUtils,Spring的BeanUtils,Cglib的BeanCopier。做法是在Eclipse新建了一個Project,專門用于專門測試幾種代碼的性能。具體的代碼如下:
                 一個FromBean和一個ToBean,兩個的代碼基本上一樣,除了類名稱不一樣,所以只是貼出來了一份。
                 
          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);
                      }

                     public  <T> T copyBeanProperties(Object sourceObj, T target, boolean useConverter) {
                          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.copyProperties54575053.666675.366666667
          PropertyUtils.copyProperties44440.4
          org.springframework.beans.BeanUtils.copyProperties121011111.1
          BeanCopier.create00000

           

          10000次測驗第一次第二次第三次平均值每次平均值
          BeanUtil.copyProperties241222226229.66670.022966667
          PropertyUtils.copyProperties92909291.333330.009133333
          org.springframework.beans.BeanUtils.copyProperties29303230.333330.003033333
          BeanCopier.create11110.1

           

          10000次反轉測驗第一次第二次第三次平均值每次平均值
          BeanUtil.copyProperties178174178176.66670.017666667
          PropertyUtils.copyProperties918789890.0089
          org.springframework.beans.BeanUtils.copyProperties212121210.0021
          BeanCopier.create0110.6666676.66667E-05


          http://www.cnblogs.com/kaka/archive/2013/03/06/2945514.html

          posted on 2017-07-25 21:53 fly 閱讀(259) 評論(0)  編輯  收藏 所屬分類: java學習
          主站蜘蛛池模板: 通渭县| 阿荣旗| 锡林浩特市| 金川县| 汽车| 张家口市| 崇阳县| 宝鸡市| 西林县| 宜章县| 新宁县| 潍坊市| 横峰县| 通化市| 池州市| 馆陶县| 隆安县| 乐平市| 石林| 昌乐县| 施甸县| 全椒县| 渭南市| 垣曲县| 虎林市| 自治县| 开原市| 仙桃市| 临泽县| 苏尼特左旗| 沾益县| 澄城县| 涟源市| 巴南区| 广水市| 郯城县| 安图县| 紫云| 云阳县| 绩溪县| 双辽市|