C# .NET 常见DeepCopy 深度拷贝的性能对比
先上结论
Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
---|---|---|---|---|---|---|
JSONConvert | 2,273.02 ns | 43.758 ns | 52.091 ns | 0.6599 | - | 4160 B |
Reflection | 1,009.13 ns | 10.110 ns | 8.442 ns | 0.0629 | - | 400 B |
BinaryFormatter | 8,146.04 ns | 85.914 ns | 67.076 ns | 1.6022 | 0.0153 | 10088 B |
Expression | 14.70 ns | 0.315 ns | 0.430 ns | 0.0063 | - | 40 B |
由测试得出结论:
1 首选Expression表达式树,性能大幅领先于反射,耗时仅为反射的1/70
2 反射,最常用的深度拷贝方法,书写比较简单
3 JSONConvert,最简答的写法,适用于偶尔需要深度拷贝的时候使用
4 BinaryFormatter,不推荐,需要在类上加上序列化声明,并且在.NET 5.0中该方法已经被微软声明为过期.
代码
public static class DeepCopyUtil
{
/// <summary>
/// Json深度拷贝
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static T DeepCopyJson<T>(T obj)
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(obj));
}
/// <summary>
/// 反射深度拷贝
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static T DeepCopyReflection<T>(T obj)
{
var type = obj.GetType();
object o = Activator.CreateInstance(type);
System.Reflection.PropertyInfo[] PI = type.GetProperties();
for (int i = 0; i < PI.Count(); i++)
{
System.Reflection.PropertyInfo P = PI[i];
P.SetValue(o, P.GetValue(obj));
}
return (T)o;
}
public static T DeepCopyMemory<T>(T obj)
{
object retval;
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
//序列化成流
bf.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
//反序列化成对象
retval = bf.Deserialize(ms);
ms.Close();
}
return (T)retval;
}
public static class TransExp<TIn, TOut>
{
private static readonly Func<TIn, TOut> cache = GetFunc();
private static Func<TIn, TOut> GetFunc()
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");
List<MemberBinding> memberBindingList = new List<MemberBinding>();
foreach (var item in typeof(TOut).GetProperties())
{
if (!item.CanWrite) continue;
MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindingList.Add(memberBinding);
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());
Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] { parameterExpression });
return lambda.Compile();
}
public static TOut Trans(TIn tIn)
{
return cache(tIn);
}
}
}
分类:
.NET
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义