Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

High Performance Cloning

Tags:

c#

clone

il

I'm after a means of deep cloning an object graph in a perfomant way. I'm going to have multiple threads cloning a graph extremely quickly such that they can play with some state and throw away the results if they're not interesting, returning to the original to try again.

I'm currently using a deep clone via binary serialization, which although it works, isn't amazingly fast. I've seen other libraries like protobuf, but the classes in my object graph may be defined in external assemblies, inheriting from classes in the main assembly and don't wish to add any complexity in those consuming assemblies if possible.

One of the interesting things I did come across was cloning using automatically generated IL. It seems it's not quite finished and I've posted to see if the author has done any more on it, but I'm guessing not. Has anyone else developed or seen a more fully functional way of deep cloning via IL? Or another method that is going to be fast?

like image 239
Ian Avatar asked Aug 19 '11 14:08

Ian


1 Answers

Other than serialisation, I only consider three options:

  • Stick with serialisation, but customise it. This might be useful if you want to declaratively bin stuff and there are very likely performance gains to be had.
  • Reflection-based object walking, in conjunction with an IL emitter such as Fasterflect.
  • Code-gen or code your own cloning by literally assigning properties to each other (we have some old code that uses what we call a copy-constructor for this, takes an instance of itself and manually copies the properties / fields across).

We have some instances of code where we control the binary serialisation so that we can serialise an interned GUID table (we have lots of repeating GUIDs and serialise very large lists over .NET Remoting). It works well for us and we haven't needed a third party serialisation framework, however, it's hand-crafted stuff with a little code-gen.

The CSLA.NET framework features a class called UndoableBase that uses reflection to serialise a Hashtable of property/field values. Used for allowing rollbacks on objects in memory. This might fit with your "returning to original to try again" sentence.

Personally I'd look further into a reflection-based (preferably with emitted IL for better performance) solution, this then allows you to take advantage of class/member attributes for control over the cloning process. If performance is king, this may not cut it.

like image 103
Adam Houldsworth Avatar answered Sep 29 '22 15:09

Adam Houldsworth