我想创建深层复制方法,我找到了3种方法来执行它
1个深度复制,每个属性1乘1
2 - 使用反射
3 - 使用序列化
请他们哪一个是表现最好的
答案 0 :(得分:13)
第一个选项是手动深度复制你的值,到目前为止效果最好。
反射会引入相当多的开销,因为它(相对)访问数据的速度很慢。
序列化增加了巨大的成本,因为它将数据序列化为临时结构,然后反转要设置的进程。这又是非常缓慢的。
选项2或3的唯一优势是它可能更容易实现,并且可以跨多种类型重用。第一个选项必须是每种类型的手写,但速度要快得多(内存使用效率也高于选项3)。
答案 1 :(得分:8)
我用三种方法和表达式树方法比较制作了图表。
对于大量对象,反射快5倍,手动代码和表达式树比序列化快20倍。因此,性能最佳的是手动代码和表达式树。
使用过的克隆代码的链接(2.-4。用作扩展方法):
答案 2 :(得分:7)
订购时,您列出的可能的解决方案是正确的性能订单。
当您编写代码以手动克隆每个属性值时,您将获得最佳性能。
反射与手动克隆有相似的结果,但速度稍慢。
序列化是最糟糕的情况。但最快实施。
Here is a good article that describes other possible solutions.
所以这里列出了所有可能的克隆方法:
我个人会选择“Clone with IL”,因为它比反射快一点,您不必手动克隆所有内容。
答案 3 :(得分:2)
最佳性能是在代码中创建克隆。所以“1”的方式。
答案 4 :(得分:1)
有ICloneable界面。如果克隆某些ICloneable,使用其方法将是最佳解决方案
答案 5 :(得分:0)
听起来你已经完成了找到方法的艰苦工作,所以现在你必须在特定的情况下测试它们并找出答案。
在大多数情况下,它实际上取决于您要序列化的数据
答案 6 :(得分:0)
可以使用反射来生成DynamicMethod,它比手动复制更有效(可以通过访问直接通过skipVisibilityCheck打破范围的字段来复制自动属性)。 DynamicMethod为您提供了一个委托,您可以将其保存在静态只读字段中以克隆您的对象。这是快速简便的方法,但不是最干净的。 序列化很慢而且没有适应。
答案 7 :(得分:0)
作为CGbR的作者,我想邀请您尝试一下您的用例。
您需要的只是nuget package和实现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<ulong> 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<ulong>(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;
}
}
效果:在我们工作所需的克隆基准测试中,将其与DataContractSerializer
和MemoryStream
进行比较。生成的代码快600倍。