Clone with better performance

前端 未结 8 2293
一整个雨季
一整个雨季 2020-12-14 04:29

I want to create deep copy method and I found 3 ways to execute it

1-deep copy with pass each property 1 by 1

2-using reflection

3-using serializatio

相关标签:
8条回答
  • 2020-12-14 04:39

    As the author of CGbR I would like to invite you to give it a try for your use case.

    All you need is the nuget package and a partial class definition that implements ICloneable. The generated will then create a file next to it with a Clone(bool deep) method.

    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;
        }
    }
    

    Performance: In a benchmark for a clone we needed at work the compared it to DataContractSerializer and MemoryStream. The generated code is 600x faster.

    0 讨论(0)
  • 2020-12-14 04:44

    Order you listed your possible solutions is correct performance order.

    You will get best performance when you write the code to clone each property value manually.

    Reflection will have similar result as manually cloning but little slower.

    Serialization is the worst scenario. But quickest to implement.

    Here is a good article that describes other possible solutions.

    So here is a list of all possible cloning methods:

    1. Clone Manually
    2. Clone with MemberwiseClone
    3. Clone with Reflection
    4. Clone with Serialization
    5. Clone with IL
    6. Clone with Extension Methods

    Me personally would go with "Clone with IL" as it is slightly faster than reflection and you don't have to clone everything manually.

    0 讨论(0)
  • 2020-12-14 04:46

    The first option, manually deep copying your values, will be the most performant by far.

    Reflection will introduce quite a bit of overhead, as it is (relatively) slow to access data.

    Serialization is adding a huge cost, as it serializes the data into a temporary structure, then reverses the process to set. This is again, very slow.

    The only advantage to option 2 or 3 is that its potentially easier to implement, and reusable across multiple types. The first option has to be hand-written per type, but is much faster (and more efficient in memory usage than option 3, as well).

    0 讨论(0)
  • 2020-12-14 04:50

    Reflection can be use to produce DynamicMethod which can be more efficient than manually copy (auto-properties can be copied by accessing fields directly breaking scope via skipVisibilityCheck). DynamicMethod offer you a delegate you can keep in static readonly field to clone your object. This is the fast and easy way to do it but not forcely the cleanest. Serialization is slow and not adapted.

    0 讨论(0)
  • 2020-12-14 04:54

    There's the ICloneable interface. If cloning something ICloneable, using its methods would be best solution

    0 讨论(0)
  • 2020-12-14 04:56

    Sounds like you've done the hard work of finding the ways to do it, so now you'll have to test them all in your specific situation and find out.

    For the most part, it really depends on what data you're serializing

    0 讨论(0)
提交回复
热议问题