C# 深度复制对象 反序列化方式与复制构造函数方式的效率分析

2022/8/17 1:56:09

本文主要是介绍C# 深度复制对象 反序列化方式与复制构造函数方式的效率分析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

先看结果

 

所以复制构造函数优于序列化和反序列化

代码如下:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 对比序列化和复制构造函数的效率
{
    internal class Program
    {
        static void Main(string[] args)
        {
            MyClass2 myClass2 = new MyClass2();
            MyClass1 myClass1 = new MyClass1() { MyClass2 = myClass2 };
            MyClass myClass = new MyClass() { MyClass1 = myClass1 };

            var newMy1 = new MyClass(myClass);

            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 100000; i++)
            {
                var newMy = SoftBasic.DeepCopy(myClass);
            }
            sw.Stop();
            Console.WriteLine($"序列化100000次耗时: {sw.ElapsedMilliseconds} ms");

            sw.Restart();
            for (int i = 0; i < 100000; i++)
            {
                var newMy = new MyClass(myClass);
            }
            sw.Stop();
            Console.WriteLine($"复制构造函数100000次耗时: {sw.ElapsedMilliseconds} ms");

            Console.ReadLine();
        }
    }

    [Serializable]
    public class MyClass
    {
        public MyClass1 MyClass1 { get; set; }

        public string Name { get; set; } = "11111111111111111111111111111111111111111111111";

        public string Description { get; set; } = "2222222222222222222222222222222222222222222";

        public int Age { get; set; } = 90909090;

        public string Address { get; set; } = "333333333333333333333333333333333333333333333333333";

        public MyClass()
        {

        }

        public MyClass(MyClass myClass)
        {
            this.MyClass1 = new MyClass1(myClass.MyClass1);
            this.Name = myClass.Name;
            this.Description = myClass.Description;
            this.Age = myClass.Age;
            this.Address = myClass.Address;
        }
    }

    [Serializable]
    public class MyClass1
    {
        public MyClass2 MyClass2 { get; set; }

        public string Name { get; set; } = "11111111111111111111111111111111111111111111111";

        public string Description { get; set; } = "2222222222222222222222222222222222222222222";

        public int Age { get; set; } = 90909090;

        public string Address { get; set; } = "333333333333333333333333333333333333333333333333333";

        public MyClass1()
        {

        }

        public MyClass1(MyClass1 myClass)
        {
            this.MyClass2 = new MyClass2(myClass.MyClass2);
            this.Name = myClass.Name;
            this.Description = myClass.Description;
            this.Age = myClass.Age;
            this.Address = myClass.Address;
        }
    }

    [Serializable]
    public class MyClass2
    {
        public string Name { get; set; } = "11111111111111111111111111111111111111111111111";

        public string Description { get; set; } = "2222222222222222222222222222222222222222222";

        public int Age { get; set; } = 90909090;

        public string Address { get; set; } = "333333333333333333333333333333333333333333333333333";

        public MyClass2()
        {

        }

        public MyClass2(MyClass2 myClass)
        {
            this.Name = myClass.Name;
            this.Description = myClass.Description;
            this.Age = myClass.Age;
            this.Address = myClass.Address;
        }
    }
}
测试Main方法
using Microsoft.VisualBasic;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;

namespace 对比序列化和复制构造函数的效率
{
    internal class SoftBasic
    {
        #region 对象与内存拷贝、交换、克隆

        /// <summary>
        /// 序列化方式对象克隆
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="RealObject"></param>
        /// <returns></returns>
        public static T Clone<T>(T RealObject)
        {
            using (Stream objectStream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objectStream, RealObject);
                objectStream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(objectStream);
            }
        }

        /// <summary>
        /// 非托管内存拷贝
        /// </summary>
        /// <param name="Destination"></param>
        /// <param name="Source"></param>
        /// <param name="Length"></param>
        [DllImport("kernel32.dll")]
        public static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length);

        /// <summary>
        /// 用序列化创建对象的深拷贝<br />
        /// 这段代码摘自《CLR via C#》
        /// </summary>
        /// <param name="original"></param>
        /// <returns></returns>
        public static object DeepClone(object original)
        {
            //构建临时内存流
            using (MemoryStream stream = new MemoryStream())
            {
                //构造序列化格式化器来执行所有实际的工作
                BinaryFormatter formatter = new BinaryFormatter();

                formatter.Context = new StreamingContext(StreamingContextStates.Clone);

                //将对象图序列化到内存流中
                formatter.Serialize(stream, original);

                //反序列化前,定位到内存流的起始位置
                stream.Position = 0;

                //将对象图反序列化成一组新对象
                //向调用者返回对象图(深拷贝)的根
                return formatter.Deserialize(stream);
            }
        }

        /// <summary>
        /// 序列化方式对象深拷贝
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="obj">对象</param>
        /// <returns>内存地址不同,数据相同的对象</returns>
        public static T DeepCopy<T>(T obj)
        {
            if (obj == null) return default(T);
            object retval = null;
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    //序列化成流
                    bf.Serialize(ms, obj);
                    ms.Seek(0, SeekOrigin.Begin);
                    //反序列化成对象

                    retval = bf.Deserialize(ms);
                }
            }
            catch (System.Runtime.Serialization.SerializationException ex)
            {
                ////Log.Error("深度拷贝对象时序列化失败:" + GetExceptionMessage(ex));
            }
            catch (System.Exception ex)
            {
                //Log.Error("深度拷贝对象时发生异常:" + GetExceptionMessage(ex));
            }
            return (T)retval;
        }

        /// <summary>
        /// 交换对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t1"></param>
        /// <param name="t2"></param>
        public static void Swap<T>(ref T t1, ref T t2)
        {
            T tem;
            tem = t2;
            t2 = t1;
            t1 = tem;
        }

        #endregion 对象与内存拷贝、交换、克隆

    }
}
序列化反序列化深度复制类

 



这篇关于C# 深度复制对象 反序列化方式与复制构造函数方式的效率分析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程