Cyg*_*gon 21
我不久前为.NET编写了三种深度克隆方法:
一个使用众所周知的BinaryFormatter技术(虽然我调整它,以便对象不需要可序列化以便克隆).这是迄今为止最慢的.
对于第二个我使用纯粹的反射.它比克隆的速度至少快6倍BinaryFormatter.这个也可用于Silverlight和.NET Compact Framework.
第三个使用Linq表达式树(用于运行时MSIL生成).它比该BinaryFormatter技术快60倍,但是在遇到每个类时,其设置时间约为2毫秒.

我在这里发布了所有三种克隆方法作为开源:
http://blog.nuclex-games.com/mono-dotnet/fast-deep-cloning/
Mar*_*ell 14
如果你在谈论一个对象树/图:
编写特定的IL以序列化对象是棘手的.IMO,你最好的选择是看一个完整的序列化,比如怎么DataContractSerializer工作 - 但不一定是那个引擎.
例如,protobuf-net有一种Serializer.DeepClone<T>可能有用的方法.它应该比DataContractSerializer至少快.目前,您需要为序列化程序添加一些线索(即使只是[ProtoContract(ImplicitFields=ImplicitFields.AllPublic)]) - 但是,当前(不完整)正在进行的工作提供了没有属性的POCO支持.
如果你在谈论个别对象:
Expression在.NET 3.5中,您可以使用相当简单的操作; Expression基于反射构建动态,并调用.Compile().MiscUtil已经有了这个:
DestType clone = PropertyCopy<DestType>.CopyFrom(original);
Run Code Online (Sandbox Code Playgroud)
使用.NET 2.0/3.0(不带Expression),您可能会将HyperDescriptor视为类似用途.
互联网上可能没有 IL Emit 制作的完整工作克隆代码。
但 IL Emit 与表达式树代码的速度相同,因为两种方法最终都会得到类似的已编译 lambda 复制函数。表达式树比反射快大约 4 倍。最棒的是,Expression Trees 的通用克隆功能可以在互联网上使用。
Cygon已经提到了表达式树的一种实现。新的经过彻底测试的实现可以在 CodeProject 文章Fast Deep Copy by Expression Trees (C#)中找到 。
使用扩展方法
var copy = originalObject.DeepCopyByExpressionTree();
Run Code Online (Sandbox Code Playgroud)
有很多库可以执行此操作.你可以看到测试结果这里:
简而言之,如果您需要性能,请手动执行,它确实更快.此外,一些库允许执行浅克隆(通过这个问题,它是适合您的好方法),这更快.BinaryFormatter如果您需要任何表现,请不要使用.
另外,@ frakon提到表达式树的速度与IL Emit相同,略有不正确.表达式树稍慢,但它可以在部分受信任的应用程序中使用.
手动13ms
DeepCloner(IL Emit)167ms
DeepCloner(表达式)267ms
CloneExtensions(表达式)560ms
NClone 901ms
Clone.Behave!8551ms
GeorgeCloney 1996ms
Nuclex.Cloning n/a(崩溃)
FastDeepCloner 1882ms
BinaryFormatter 15000ms
| 归档时间: |
|
| 查看次数: |
16108 次 |
| 最近记录: |