




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第C#深拷贝方法探究及性能比较(多种深拷贝)目录1、手写创建对象2、反射3、Json字符串序列化4、对象二进制序列化5、AutoMapper6、表达式树之前学习了设计模式原型模式,在原型模式中就提到了对象的深拷贝。深拷贝指的是拷贝一个对象时,不仅仅把对象的引用进行复制,还把该对象引用的值也一起拷贝。与浅拷贝不同的就是,深拷贝后的拷贝对象就和源对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。
在查询资料之后,探究了以下几种C#对象深拷贝方式,同时简单对比了以下列出的几种深拷贝方式的速度(简单测试,仅测试对象深拷贝速度,不考虑性能影响)。
测试平台:Intel9700K+DDR4360032G,框架为.NET5.0。测试方式为创建100万次,比较执行时间。拷贝的对象如下:
[Serializable]
classUserInfo
publicstringName{get;set;}
publicstringUserId{get;set;}
publicintAge{get;set;}
publicstringAddress{get;set;}
publiclongUpdateTime{get;set;}
publiclongCreateTime{get;set;}
}
1、手写创建对象
简单对象创建,不考虑有构造函数的情况。
NewUserInfonewInfo=newNewUserInfo()
Name=info.Name,
Age=info.Age,
UserId=info.UserId,
Address=info.Address,
UpdateTime=info.UpdateTime,
CreateTime=info.CreateTime,
};
100万次执行时间为39.4073ms,位居第一。当然,在这种不考虑构造函数的情况下,手写创建肯定是最快的。但是同时,如果遇到复杂对象,代码量也是最多的。
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万次执行时间为1618.4662ms,平均执行时间为0.001618,看起来还行。
3、Json字符串序列化
使用System.Text.Json作为序列化和反序列化工具。
UserInfonewInfo=JsonSerializer.DeserializeUserInfo(JsonSerializer.Serialize(info));
100万次执行时间为2222.2078ms,比反射慢一点点。
4、对象二进制序列化
首先不推荐使用这种方式,一是BinaryFormatter.Serialize微软已不推荐使用(据微软官网文档说是有漏洞,具体有什么漏洞没细究),二是必须在要序列化的对象上面写上Serializable的关键字,三是速度并不理想。
privatestaticTOutObjectMemoryConvertTIn,TOut(TIntIn)
using(MemoryStreamms=newMemoryStream())
BinaryFormatterformatter=newBinaryFormatter();
formatter.Serialize(ms,tIn);
ms.Position=0;
return(TOut)formatter.Deserialize(ms);
}
100万次执行时间为8545.9835ms,讲道理应该是比Json序列化要更快的,但是实际上慢了许多。
5、AutoMapper
熟悉的AutoMapper,性能也没有让我们失望。
//循环外创建MapperConfig
varconfig=newMapperConfiguration(cfg=cfg.CreateMapUserInfo,UserInfo
varmapper=config.CreateMapper();
//循环内调用
UserInfonewInfo=mapper.MapUserInfo(info);
100万次执行时间为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万次执行时间为77.3653ms,位居第二。仅比手写慢一点点。
简单整理成柱状图,可以很清晰的对比出这几种深拷贝方式之间的速度差距。总结来说就是,一般简单的对象深拷贝,推荐直接手写,复杂对象深拷贝,推荐使用表达式树。当然,如果创建对象中还涉及到构造函数初始化,那又是不同的情况,这里暂不讨论。
附上本次测试用的完整代码。
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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 四川省成都市简阳市阳安中学2022-2023学年高一下学期3月月考地理试题 无答案
- 终止加盟合同协议书范本
- 合同弃权协议书
- 中国新质生产力技术
- 协议入股合同协议书
- 纺织材料的创新使用与环境影响试题及答案
- 佛教合同协议书
- 合同金额协议书
- 果园种植合同协议书模板
- 美工合同协议书
- 2021-2022学年浙江省“9 1”高中联盟高一年级下册学期期中数学试题【含答案】
- 硬笔书法:幼小衔接识字写字教学课件
- 盘扣支模架工程监理细则
- 崇尚科学反邪教主题教育PPT反对邪教主题教育宣讲课件
- smt首件检验记录表
- 大众Formel-Q培训材料全解析含案例
- 莫扎特贝多芬肖邦英文简介课件
- 青岛中瑞泰丰新材料有限公司2万吨无机环保新材料来料加工项目 环境影响报告书
- 《现代汉语词汇》PPT课件(教学)
- 编码理论第3章
- 北京市46家种猪场地址及联系方式
评论
0/150
提交评论