ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2022-08-16 10:01:03  阅读:126  来源: 互联网

标签:System new 复制 myClass using 序列化 public 构造函数


先看结果

 

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

代码如下:

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 对象与内存拷贝、交换、克隆

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

 

标签:System,new,复制,myClass,using,序列化,public,构造函数
来源: https://www.cnblogs.com/yangmengke2018/p/16590580.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有