高性能克隆

8
我需要一种高效的方式来深度克隆一个对象图。我将有多个线程快速地克隆一个图,以便他们可以操作一些状态并在结果不感兴趣时放弃,返回原始状态重新尝试。
目前,我正在使用通过二进制序列化实现的深度克隆,虽然它能工作,但速度并不是很快。我看到了其他库,比如protobuf,但我的对象图中的类可能是在外部程序集中定义的,继承自主程序集中的类,如果可能的话,我不希望在那些消费程序集中添加任何复杂性。
我发现有趣的一件事是使用自动生成的IL进行克隆。它似乎还没有完全完成,我已经发布了消息以了解作者是否有更多的进展,但我猜想没有。是否有其他人开发或看到了更完整的通过IL进行深度克隆的方法?或者其他更快的方法?

抱歉,我犯了一个错误。根据您的要求,我将不会提供任何翻译内容。 - Tejs
@Tejs:如果你仔细阅读问题,他正在使用那个。 - sehe
你了解图形结构的特殊性吗?例如,分支是否可以引用其他分支?你能假设某种平衡、正常的结构(例如:二叉树)吗? - Paul Williams
@Paul:完全图在分支之间会有引用,尽管我可能可以相对容易地将其隔离。在那一点上,我认为任何交叉引用都可以被忽略并且复制,因为它们没有任何状态。我可能会尝试生成一个示例图并上传它。 - Ian
1个回答

3

除了序列化,我只考虑三个选项:

  • 继续使用序列化,但进行自定义。如果您想要声明式地将东西放入bin中,并且很可能会有性能提升,则这可能非常有用。
  • 基于反射的对象遍历,结合类似 Fasterflect 的 IL 发射器。
  • 代码生成或通过直接将属性相互赋值来编写自己的克隆(我们有一些旧代码使用所谓的复制构造函数,需要一个自身实例并手动复制属性/字段)。

我们有一些控制二进制序列化的代码实例,以便我们可以序列化一个已经存在的 GUID 表(我们有许多重复的 GUID 并在 .NET Remoting 上序列化非常大的列表)。 对我们来说效果很好,我们没有需要第三方序列化框架,但这是手工制作的东西,带有一些代码生成。

CSLA.NET framework 中有一个名为 UndoableBase 的类,它使用反射来序列化属性/字段值的 Hashtable。该功能用于允许对内存中的对象进行回滚操作。这可能符合您提到的“返回原始状态以重试”的需求。

就个人而言,我建议进一步研究基于反射的解决方案(最好使用发出的 IL 以获得更好的性能),这样可以利用类/成员属性来控制克隆过程。但是,如果性能至关重要,则该方案可能无法满足要求。


Adam:虽然自己克隆可以工作,但我觉得会带来相当大的维护开销,自定义序列化也是如此(但对于明显的建议+1)。你能给我更多关于Fasterflect建议的细节吗? - Ian
@Ian,我建议将Fasterflect作为反射解决方案的补充。我相信它可以在第一次调用时发出IL来直接完成反射任务,从而使后续调用更快。至于手动复制,可以通过开发简单的代码生成工具将复制构造函数输出到要克隆的类的部分类中来减轻维护工作。 - Adam Houldsworth
@Ian 我们使用代码生成工具遍历字段/属性并输出序列化和反序列化的“读/写”对。唯一需要维护的是确保在类更改时使用工具。我们的工具不是用于克隆,而是用于.NET Remoting支持。但是思路是相同的。 - Adam Houldsworth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接