I wonder what is the fastest way to do shallow copying in C#? I only know there are 2 ways to do shallow copy:
- MemberwiseClone
- Copy each field one by one (manual)
I found that (2) is faster than (1). I'm wondering if there's another way to do shallow copying?
MemberwiseClone requires less maintenance. I don't know if having default property values helps any, maybe if could ignore items with default values.
In fact, MemberwiseClone is usually much better than others, especially for complex type.
The reason is that:if you manual create a copy, it must call one of the type's constructor, but use memberwise clone, I guess it just copy a block of memory. for those types has very expensive construct actions, memberwise clone is absolutely the best way.
Onece i wrote such type: {string A = Guid.NewGuid().ToString()}, I found memberwise clone is muct faster than create a new instance and manual assign members.
The code below's result:
Manual Copy:00:00:00.0017099
MemberwiseClone:00:00:00.0009911
finally, I provide my code here:
This is a complex subject with lots of possible solutions and many pros and cons to each. There is a wonderful article here that outlines several different ways of making a copy in C#. To summarize:
Clone Manually
Tedious, but high level of control.
Clone with MemberwiseClone
Only creates a shallow copy, i.e. for reference-type fields the original object and its clone refer to the same object.
Clone with Reflection
Shallow copy by default, can be re-written to do deep copy. Advantage: automated. Disadvantage: reflection is slow.
Clone with Serialization
Easy, automated. Give up some control and serialization is slowest of all.
Clone with IL, Clone with Extension Methods
More advanced solutions, not as common.
This is a way to do it using dynamic IL generation. I found it somewhere online:
Why complicate things? MemberwiseClone would suffice.
I'm confused.
MemberwiseClone()
should annihilate the performance of anything else for a shallow copy. In the CLI, any type other than an RCW should be able to be shallow-copied by the following sequence:memcpy
the data from the original to the new. Since the target is in the nursery, no write barriers are required.SuppressFinalize
called on it and such a flag is stored in the object header, unset it in the clone.Can someone on the CLR internals team explain why this is not the case?