BeanUtils.copyProperties 和 fastjson 性能對比
聲明
測試方法非嚴格方式, 測試結果以及結論僅供參考!
測試方法非嚴格方式, 測試結果以及結論僅供參考!
測試方法非嚴格方式, 測試結果以及結論僅供參考!
運行環境
- cpu: i5-8400(6c 6t 3.8主頻)
- 內存: 16G(2666頻率)*2
- 系統: Mac OS 10.14.6 (18G95)
- java環境: jdk1.8.0_171
測試樣本
用json輸出大概是7kb
對比測試方法
BeanUtils.copyProperties
有的字段無法正確複製, 我們用json
序列化(兼容性好)來進行對比測試
json
工具使用的是阿里 fastJson
由於測試循環中加入了一個檢測是否新建對象的邏輯(防止程序自動優化出現假的字段拷貝), 所以實際執行時間會比給出的測試耗時要稍微短一點
第一輪測試(10次循環)
測試次數
10次循環
測試結果
測試結果相差無幾, 有時 BeanUtils
快點, 有時 json
的方式快點, 應該是樣本量太小導致成績受系統波動的影響太大
第二輪測試(100次循環)
測試次數
100次循環
測試結果
序號 | 方式 | 耗時 |
---|---|---|
1 | BeanUtils | 4ms |
1 | json | 41ms |
2 | BeanUtils | 4ms |
2 | json | 47ms |
3 | BeanUtils | 1ms |
3 | json | 13ms |
4 | BeanUtils | 1ms |
4 | json | 11ms |
已經體現出一些差距了
第三輪測試(1000次循環)
測試次數
1000次循環
測試結果
序號 | 方式 | 耗時 |
---|---|---|
1 | BeanUtils | 8ms |
1 | json | 110ms |
2 | BeanUtils | 3ms |
2 | json | 61ms |
3 | BeanUtils | 2ms |
3 | json | 67ms |
4 | BeanUtils | 3ms |
4 | json | 67ms |
1000次循環的輕度下大約是20倍的性能差距, 不過波動還是比較大, 我們繼續增加次數
第四輪測試(10000次循環)
測試次數
10000次循環
測試結果
序號 | 方式 | 耗時 |
---|---|---|
1 | BeanUtils | 33ms |
1 | json | 638ms |
2 | BeanUtils | 33ms |
2 | json | 643ms |
3 | BeanUtils | 25ms |
3 | json | 621ms |
4 | BeanUtils | 31ms |
4 | json | 630ms |
還是大約是20倍左右的性能差距, 第三組蹦躂到快25倍了
第五輪測試(200000次循環)
測試次數
200000次循環
測試結果
依舊是20倍左右的差距, 循環200000次但新建對象不是預期的200000而總是少10個左右…
結論
使用 BeanUtils
自動複製字段, 性能大概是 json序列化
方式複製字段的20倍
, 不過如果對象不是十分複雜, 這個差距可以接受, 性能不敏感的話可以考慮使用 json序列化
的方式進行字段複製
源碼
測試關鍵邏輯源碼
final int testNums = 200000;
Map<String, String> map = Maps.newHashMap("key", "value");
long startTime1 = nowMillis();
int num = testNums;
int count = 0;
while (num > 0) {
num--;
count++;
Page<EvaluationUserWithResult> tempReturnPage = new Page<>();
BeanUtils.copyProperties(evaluationUserPage, tempReturnPage);
map.put(tempReturnPage.hashCode() + "", tempReturnPage.hashCode() +"");
}
log.error("beanutil循環{}次, 新建臨時對象{}個, 用時{}", count, map.size()-1, DateTimeStyle.duration(startTime1));
long startTime2 = nowMillis();
num = testNums;
map = Maps.newHashMap("key", "value");
count = 0;
while (num > 0) {
num--;
count++;
Page<EvaluationUserWithResult> tempReturnPage = new Page<>();
tempReturnPage = JSON.parseObject(JSON.toJSONString(evaluationUserPage), tempReturnPage.getClass());
map.put(tempReturnPage.hashCode() + "", tempReturnPage.hashCode() +"");
}
log.error("json循環{}次, 新建臨時對象{}個, 用時{}", count, map.size()-1, DateTimeStyle.duration(startTime2));
樣本數據
{
"code": 0,
"msg": "成功",
"data": {
"itemsWithResult": [
{
"maxProgress": 6,
"hmoId": "CYH3211204110000",
"medChannel": 2,
"updateTime": 1569746589000,
"evaluationTime": 1569746589000,
"userName": "202",
"itemsResult": {
"bc": "",
"op": "較高風險",
"dyslipemia": "高危",
"diab": "已患病",
"lungcnacer": "暫無風險",
"stroke": "中危人羣",
"cvd": "較高風險",
"pc": "暫無風險",
"sportrisk": "較高風險",
"hbp": "高風險",
"疾病類型": "疾病風險程度",
"depression": "可能有重度抑鬱傾向",
"obesity": "正常"
},
"userAge": 39,
"evaluationId": "8a3147b08opsf878da8622525389fd26",
"userUnit": "gryh",
"createTime": 1569745748000,
"medChannelDesc": "醫生錄入",
"userMobile": "99300000202",
"progress": 6,
"personId": "test2",
"userGender": 1,
"id": 546,
"evaluationKey": "PersonalHealthRiskEvaluation",
"evaluationState": 1
},
{
"maxProgress": 6,
"hmoId": "CYH3211204110000",
"medChannel": 2,
"updateTime": 1569745630000,
"evaluationTime": 1569745629000,
"userName": "32423",
"itemsResult": {
"bc": "",
"op": "較低風險",
"dyslipemia": " 低危",
"diab": "已患病",
"lungcnacer": "暫無風險",
"stroke": "高危人羣",
"cvd": "中等風險",
"pc": "高危",
"sportrisk": "較高風險",
"hbp": "已異常",
"疾病類型": "疾病風險程度",
"depression": "可能有重度抑鬱傾向",
"obesity": "正常"
},
"userAge": 39,
"evaluationId": "833a6eac1dbss673f54f44f5c1c62d7a",
"userUnit": "gryh",
"createTime": 1563876718000,
"medChannelDesc": "醫生錄入",
"userMobile": "15999999999",
"progress": 6,
"personId": "test2",
"userGender": 1,
"id": 495,
"evaluationKey": "PersonalHealthRiskEvaluation",
"evaluationState": 1
},
{
"maxProgress": 6,
"hmoId": "CYH3211204110000",
"medChannel": 2,
"updateTime": 1563876694000,
"evaluationTime": 1563876693000,
"userName": "測試",
"itemsResult": {
"bc": "",
"op": "較低風險",
"dyslipemia": " 低危",
"diab": "高風險",
"lungcnacer": " 低危",
"stroke": "低危人羣",
"cvd": "較低風險",
"pc": "高危",
"sportrisk": "中等風險",
"hbp": "中等風險",
"疾病類型": "疾病風險程度",
"depression": "可能有中重度抑鬱傾向",
"obesity": "正常"
},
"userAge": 39,
"evaluationId": "2a9ggg508e47412fc5cc092d7ae7c05e",
"userUnit": "gryh",
"createTime": 1557737311000,
"medChannelDesc": "醫生錄入",
"userMobile": "15999930566",
"progress": 6,
"personId": "test1",
"userGender": 1,
"id": 487,
"evaluationKey": "PersonalHealthRiskEvaluation",
"evaluationState": 1
},
{
"maxProgress": 7,
"hmoId": "CYH3211204110000",
"medChannel": 1,
"updateTime": 1562763683000,
"evaluationTime": 1557473650000,
"userName": "測試2",
"itemsResult": {
"bc": "較高風險",
"op": "較低風險",
"dyslipemia": " 低危",
"diab": "高風險",
"lungcnacer": "暫無風險",
"stroke": "低危人羣",
"cvd": "高風險",
"pc": "",
"sportrisk": "較低風險",
"hbp": "高風險",
"疾病類型": "疾病風險程度",
"depression": "可能有中度抑鬱傾向",
"obesity": "超重"
},
"userAge": 39,
"evaluationId": "ba8cd69396f3603e6e7b27e7f77d5a4a",
"userUnit": "gryh",
"createTime": 1557473530000,
"medChannelDesc": "用戶填寫",
"userMobile": "手機號2",
"progress": 7,
"personId": "test3",
"userGender": 2,
"id": 483,
"evaluationKey": "PersonalHealthRiskEvaluation",
"evaluationState": 4
},
{
"maxProgress": 6,
"hmoId": "CYH3211204110000",
"medChannel": 1,
"updateTime": 1557473641000,
"evaluationTime": 1557473641000,
"userName": "測試2",
"itemsResult": {
"bc": "",
"op": "較低風險",
"dyslipemia": " 低危",
"diab": "高風險",
"lungcnacer": "暫無風險",
"stroke": "低危人羣",
"cvd": "較高風險",
"pc": "極高危",
"sportrisk": "中等風險",
"hbp": "高風險",
"疾病類型": "疾病風險程度",
"depression": "可能有重度抑鬱傾向",
"obesity": "超重"
},
"userAge": 39,
"evaluationId": "edf65b5a233cfd2eggf1c548374cde8f",
"userUnit": "gryh",
"createTime": 1557473249000,
"medChannelDesc": "用戶填寫",
"userMobile": "手機號2",
"progress": 6,
"personId": "test",
"userGender": 1,
"id": 482,
"evaluationKey": "PersonalHealthRiskEvaluation",
"evaluationState": 1
}
],
"pageNo": 1,
"pageSize": 5,
"pageCount": 3,
"recordCount": 13
}
}