克隆具有更好的性能

我想创建深度复制方法,我找到了3种方法来执行它

1个深度复制,每个属性1乘1

2 – 使用reflection

3 – 使用序列化

请他们哪个是表现最好的

第一个选项,手动深度复制您的值,将是迄今为止最高效的。

reflection将引入相当多的开销,因为它(相对)访问数据很慢。

序列化增加了巨大的成本,因为它将数据序列化为临时结构,然后反转要设置的进程。 这又是非常缓慢的。

选项2或3的唯一优势是它可能更容易实现,并且可以跨多种类型重用。 第一个选项必须是每种类型的手写,但速度要快得多(并且内存使用效率也高于选项3)。

我用三种方法和表达式树方法比较制作了图形。

在此处输入图像描述

对于大量对象, reflection速度提高了5倍手动代码和表达式树比序列化快20倍 。 因此,性能最佳的是手动代码和表达式树。

使用过的克隆代码的链接(2.-4。用作扩展方法):

  1. 手动 :手动编写,无链接。
  2. 通过序列化克隆
  3. 通过反思克隆
  4. 通过表达式树克隆

订购您列出的可能的解决方案是正确的性能订单。

编写代码以手动克隆每个属性值时,您将获得最佳性能。

reflection将具有与手动克隆类似的结果,但速度稍慢。

序列化是最糟糕的情况。 但最快实施。

这是一篇描述其他可能解决方案的好文章。

所以这里列出了所有可能的克隆方法:

  1. 手动克隆
  2. 使用MemberwiseClone进行克隆
  3. 用reflection克隆
  4. 克隆序列化
  5. 用IL克隆
  6. 用扩展方法克隆

我个人会选择“ 克隆与IL ”,因为它比reflection快一点,你不必手动克隆一切。

性能最佳的是在代码中创建克隆。 所以“1”的方式。

有ICloneable接口。 如果克隆ICloneable的东西,使用它的方法将是最好的解决方案

听起来你已经完成了找到方法的艰苦工作,所以现在你必须在你的具体情况下测试它们并找出答案。

在大多数情况下,它实际上取决于您要序列化的数据

reflection可以用于生成DynamicMethod,它比手动复制更有效(可以通过访问直接通过skipVisibilityCheck破坏范围的字段来复制自动属性)。 DynamicMethod为您提供了一个委托,您可以将其保存在静态只读字段中以克隆您的对象。 这是快速简便的方法,但不是最干净的。 序列化很慢而且没有适应。

作为CGbR的作者,我想邀请您尝试一下您的用例。

您只需要nuget包和实现ICloneable的部分类定义。 然后生成的将使用Clone(bool deep)方法在其旁边创建一个文件。

 public partial class Root : ICloneable { public Root(int number) { _number = number; } private int _number; public Partial[] Partials { get; set; } public IList Numbers { get; set; } public object Clone() { return Clone(true); } private Root() { } } public partial class Root { public Root Clone(bool deep) { var copy = new Root(); // All value types can be simply copied copy._number = _number; if (deep) { // In a deep clone the references are cloned var tempPartials = new Partial[Partials.Length]; for (var i = 0; i < Partials.Length; i++) { var value = Partials[i]; value = value.Clone(true); tempPartials[i] = value; } copy.Partials = tempPartials; var tempNumbers = new List(Numbers.Count); for (var i = 0; i < Numbers.Count; i++) { var value = Numbers[i]; tempNumbers[i] = value; } copy.Numbers = tempNumbers; } else { // In a shallow clone only references are copied copy.Partials = Partials; copy.Numbers = Numbers; } return copy; } } 

性能:在我们工作所需的克隆基准测试中,将其与DataContractSerializerMemoryStream 。 生成的代码快600倍。