公司系統中以前一直有使用組件進行Bean copy的操做,只是知道此操做對性能有影響,可是到底有多少影響內心一直沒有數。如今對Bean copy進行測試獲取量化的結果java
目前Bean Copy的主流組件:spring
Apache BeanUtils緩存
Spring BeanUtilsbash
Cglib BeanCopier多線程
衆所周知Apache BeanUtils性能太差,通常不推薦使用。這裏不對其進行測試,只測試後面兩個組件app
測試功能:循環N次,將TelAppModel 對象中的屬性複製到TelAppDto中,統計每種組件花費的時間,花費時間越少的性能越強。oop
測試POJO類 源類 TelAppModel.java 和目標類 TelAppDto.java,兩個類都是簡單的pojo類且成員變量相同。性能
普通的Java set/get方法實現Bean Copy, 代碼以下:測試
public static void copySetGet(TelAppModel source, TelAppDto target){
target.setId(source.getId());
target.setTelPowerSavingMode((byte)0);
target.setTelSecret(source.getTelSecret());
target.setTelAppId(source.getTelAppId());
target.setTelName(source.getTelName());
target.setDesc(source.getDesc());
}
複製代碼
Spring BeanUtils實現Bean Copy代碼以下:優化
public static void copyPropertiesSpring(Object source, Object target){
BeanUtils.copyProperties(source, target);
}
複製代碼
Cglib BeanCopier實現Bean Copy代碼以下:
public static void copyPropertiesCglib(Object source, Object target){
BeanCopier beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
beanCopier.copy(source, target, null);
}
複製代碼
測試代碼: longCount:定義複製執行的次數
// 在執行Bean copy前 先初始化 longCount 個TelAppModel,作爲測試素材
for(int i = 0; i < longCount; i++){
appModelSourceList.add(createModel());
}
複製代碼
3種Bean copy方法依次調用此test()方法:
// set/get方法
test((a,b) -> copySetGet(a, b));
// spring BeanUtils
test((a,b) -> copyPropertiesSpring(a, b));
// spring BeanCopier
test((a,b) -> copyPropertiesCglib(a, b));
複製代碼
// 此方法依次將列表中TelAppModel對象複製到TelAppDto對象中,並打印執行longCount次花費的時間,爲了保證結果準確,以上操做執行3次,即3*longCount次
private void test(BiConsumer<TelAppModel, TelAppDto> biConsumer){
int runNum = 3;
for(int k = 0; k < runNum; k++) {
long loopCount = longCount;
long begin = System.currentTimeMillis();
for (int i = 0; i < loopCount; i++) {
TelAppModel telAppModel1 = appModelSourceList.get(i);
TelAppDto telAppDto = new TelAppDto();
biConsumer.accept(telAppModel1, telAppDto);
}
System.out.println((System.currentTimeMillis() - begin));
}
}
複製代碼
分別執行1000、10000、100000、1000000次耗時數(毫秒): 詳細時間以下:
數據分析:在執行命令時,經過jvisualvm查看CPU的耗時時間,詳細以下:
圖表分析:static BeanCopier beanCopierStatic = BeanCopier.create(TelAppModel.class, TelAppDto.class, false);
public static void copyPropertiesCglibStatic(Object source, Object target){
beanCopierStatic.copy(source, target, null);
}
複製代碼
再分別執行1000、10000、100000、1000000次耗時數(毫秒): 詳細時間以下:
分析: Cglib BeanCopier優化,性能大大提升。cglib在性能和set/get方法相差不大
spring beanUtils 和 cglib 性能都還能夠接受,若是對性能沒有很是苛刻的要求,使用cglib或spring bean utils 問題都問題不大,推薦優先使用cglib
複製代碼