




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第C#深拷貝方法探究及性能比較(多種深拷貝)目錄1、手寫創(chuàng)建對象2、反射3、Json字符串序列化4、對象二進制序列化5、AutoMapper6、表達式樹之前學習了設計模式原型模式,在原型模式中就提到了對象的深拷貝。深拷貝指的是拷貝一個對象時,不僅僅把對象的引用進行復制,還把該對象引用的值也一起拷貝。與淺拷貝不同的就是,深拷貝后的拷貝對象就和源對象互相獨立,其中任何一個對象的改動都不會對另外一個對象造成影響。
在查詢資料之后,探究了以下幾種C#對象深拷貝方式,同時簡單對比了以下列出的幾種深拷貝方式的速度(簡單測試,僅測試對象深拷貝速度,不考慮性能影響)。
測試平臺:Intel9700K+DDR4360032G,框架為.NET5.0。測試方式為創(chuàng)建100萬次,比較執(zhí)行時間??截惖膶ο笕缦拢?/p>
[Serializable]
classUserInfo
publicstringName{get;set;}
publicstringUserId{get;set;}
publicintAge{get;set;}
publicstringAddress{get;set;}
publiclongUpdateTime{get;set;}
publiclongCreateTime{get;set;}
}
1、手寫創(chuàng)建對象
簡單對象創(chuàng)建,不考慮有構造函數(shù)的情況。
NewUserInfonewInfo=newNewUserInfo()
Name=info.Name,
Age=info.Age,
UserId=info.UserId,
Address=info.Address,
UpdateTime=info.UpdateTime,
CreateTime=info.CreateTime,
};
100萬次執(zhí)行時間為39.4073ms,位居第一。當然,在這種不考慮構造函數(shù)的情況下,手寫創(chuàng)建肯定是最快的。但是同時,如果遇到復雜對象,代碼量也是最多的。
2、反射
這也是在日常代碼中最常用的方式之一。
privatestaticTOutTransReflectionTIn,TOut(TIntIn)
TOuttOut=Activator.CreateInstanceTOut
vartInType=tIn.GetType();
foreach(varitemOutintOut.GetType().GetProperties())
varitemIn=tInType.GetProperty(itemOut.Name);;
if(itemIn!=null)
itemOut.SetValue(tOut,itemIn.GetValue(tIn));
returntOut;
}
調用
NewUserInfonewInfo=TransReflectionUserInfo,NewUserInfo(info);
100萬次執(zhí)行時間為1618.4662ms,平均執(zhí)行時間為0.001618,看起來還行。
3、Json字符串序列化
使用System.Text.Json作為序列化和反序列化工具。
UserInfonewInfo=JsonSerializer.DeserializeUserInfo(JsonSerializer.Serialize(info));
100萬次執(zhí)行時間為2222.2078ms,比反射慢一點點。
4、對象二進制序列化
首先不推薦使用這種方式,一是BinaryFormatter.Serialize微軟已不推薦使用(據(jù)微軟官網(wǎng)文檔說是有漏洞,具體有什么漏洞沒細究),二是必須在要序列化的對象上面寫上Serializable的關鍵字,三是速度并不理想。
privatestaticTOutObjectMemoryConvertTIn,TOut(TIntIn)
using(MemoryStreamms=newMemoryStream())
BinaryFormatterformatter=newBinaryFormatter();
formatter.Serialize(ms,tIn);
ms.Position=0;
return(TOut)formatter.Deserialize(ms);
}
100萬次執(zhí)行時間為8545.9835ms,講道理應該是比Json序列化要更快的,但是實際上慢了許多。
5、AutoMapper
熟悉的AutoMapper,性能也沒有讓我們失望。
//循環(huán)外創(chuàng)建MapperConfig
varconfig=newMapperConfiguration(cfg=cfg.CreateMapUserInfo,UserInfo
varmapper=config.CreateMapper();
//循環(huán)內調用
UserInfonewInfo=mapper.MapUserInfo(info);
100萬次執(zhí)行時間為267.5073ms,位居第三。
6、表達式樹
重頭戲來了,此處代碼來源于文首中的博客中,性能讓人大吃一驚。其原理是反射和表達式樹相結合,先用反射獲取字段然后緩存起來,再用表達式樹賦值。
publicstaticclassTransExpTIn,TOut
privatestaticreadonlyFuncTIn,TOutcache=GetFunc();
privatestaticFuncTIn,TOutGetFunc()
ParameterExpressionparameterExpression=Expression.Parameter(typeof(TIn),"p");
ListMemberBindingmemberBindingList=newListMemberBinding
foreach(varitemintypeof(TOut).GetProperties())
if(!item.CanWrite)continue;
MemberExpressionproperty=Expression.Property(parameterExpression,typeof(TIn).GetProperty(item.Name));
MemberBindingmemberBinding=Expression.Bind(item,property);
memberBindingList.Add(memberBinding);
MemberInitExpressionmemberInitExpression=Expression.MemberInit(Expression.New(typeof(TOut)),memberBindingList.ToArray());
ExpressionFuncTIn,TOutlambda=Expression.LambdaFuncTIn,TOut(memberInitExpression,newParameterExpression[]{parameterExpression});
returnlambda.Compile();
publicstaticTOutTrans(TIntIn)
returncache(tIn);
}
調用
UserInfonewInfo=TransExpUserInfo,UserInfo.Trans(info);
100萬次執(zhí)行時間為77.3653ms,位居第二。僅比手寫慢一點點。
簡單整理成柱狀圖,可以很清晰的對比出這幾種深拷貝方式之間的速度差距??偨Y來說就是,一般簡單的對象深拷貝,推薦直接手寫,復雜對象深拷貝,推薦使用表達式樹。當然,如果創(chuàng)建對象中還涉及到構造函數(shù)初始化,那又是不同的情況,這里暫不討論。
附上本次測試用的完整代碼。
usingAutoMapper;
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Diagnostics;
usingSystem.IO;
usingSystem.Linq.Expressions;
usingSystem.Runtime.Serialization;
usingSystem.Runtime.Serialization.Formatters.Binary;
usingSystem.Text.Json;
usingSystem.Threading.Tasks;
namespaceTestObjectDeepCopy
classProgram
staticvoidMain(string[]args)
UserInfoinfo=newUserInfo()
Name="張三",
Age=18,
UserId=Guid.NewGuid().ToString("N"),
Address="銀河系地球中國",
UpdateTime=1615888888,
CreateTime=1615895454,
varconfig=newMapperConfiguration(cfg=cfg.CreateMapUserInfo,UserInfo
varmapper=config.CreateMapper();
intcount=1000000;
Stopwatchsw=newStopwatch();
sw.Start();
for(inti=-0;icount;i++)
//手寫39.4073ms
//UserInfonewInfo=newUserInfo()
//Name=info.Name,
//Age=info.Age,
//UserId=info.UserId,
//Address=info.Address,
//UpdateTime=info.UpdateTime,
//CreateTime=info.CreateTime,
//};
//反射1618.4662ms
//UserInfonewInfo=TransReflectionUserInfo,UserInfo(info);
//Json字符串序列化2222.2078ms
//UserInfonewInfo=JsonSerializer.DeserializeUserInfo(JsonSerializer.Serialize(info));
//對象二進制序列化8545.9835ms
//UserInfonewInfo=ObjectMemoryConvertUserInfo,UserInfo(info);
//表達式樹77.3653ms
//UserInfonewInfo=TransExpUserInfo,UserInfo.Trans(info);
//AutoMapper267.5073ms
//UserInfonewInfo=mapper.MapUserInfo(info);
Console.WriteLine("總共花費{0}ms.",sw.Elapsed.TotalMilliseconds);
sw.Stop();
Console.ReadKey();
privatestaticTOutTransReflectionTIn,TOut(TIntIn)
TOuttOut=Activator.CreateInstanceTOut
vartInType=tIn.GetType();
foreach(varitemOutintOut.GetType().GetProperties())
varitemIn=tInType.GetProperty(itemOut.Name);;
if(itemIn!=null)
itemOut.SetValue(tOut,itemIn.GetValue(tIn));
returntOut;
privatestaticTOutObjectMemoryConvertTIn,TOut(TIntIn)
using(MemoryStreamms=newMemoryStream())
BinaryFormatterformatter=newBinaryFormatter();
formatter.Serialize(ms,tIn);
ms.Position=0;
return(TOut)formatter.Deserialize(ms);
publicstaticclassTransExpTIn,TOut
privatestaticreadonlyFuncTIn,TOutcache=GetFunc();
privatestaticFuncTIn,TOutGetFunc()
ParameterExpressionparameterExpression=Expression.Parameter(typeof(TIn),"p");
ListMemberBindingmemberBindingList=newListMemberBinding
foreach(varitemintypeof(TOut).GetProperties())
if(!item.CanWrite)continue;
MemberExpressionproperty=Expression.Property(parameterExpression,typeof(TIn).GetProperty(item.Name));
MemberBindingmemberBindin
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 光伏電站個人年終總結模版
- 從概念到落地探討如何利用區(qū)塊鏈推動企業(yè)數(shù)字化轉型
- 倉庫廠房加盟合同范例
- 2025年初中數(shù)學教師年度考核個人總結模版
- 低價漁具轉讓合同范例
- 中介住宅租賃合同范例
- 在家長會上的小學生發(fā)言稿模版
- 創(chuàng)新研發(fā)背景下科技企業(yè)市場擴張風險控制策略
- 中英雙語購銷合同范例
- 醫(yī)療大數(shù)據(jù)時代的醫(yī)療質量管理
- 兒童換牙期健康課件
- 2021-2022學年浙江省“9 1”高中聯(lián)盟高一年級下冊學期期中數(shù)學試題【含答案】
- 硬筆書法:幼小銜接識字寫字教學課件
- 盤扣支模架工程監(jiān)理細則
- 崇尚科學反邪教主題教育PPT反對邪教主題教育宣講課件
- smt首件檢驗記錄表
- 大眾Formel-Q培訓材料全解析含案例
- 青島中瑞泰豐新材料有限公司2萬噸無機環(huán)保新材料來料加工項目 環(huán)境影響報告書
- 《現(xiàn)代漢語詞匯》PPT課件(教學)
- 編碼理論第3章
- 北京市46家種豬場地址及聯(lián)系方式
評論
0/150
提交評論