首页 > 编程语言 >C# 深度复制对象 反序列化方式与复制构造函数方式的效率分析

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

时间:2022-08-16 10:01:20浏览次数:73  
标签: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,构造函数
From: https://www.cnblogs.com/yangmengke2018/p/16590580.html

相关文章

  • 第二十三天,序列化与反序列化
    1.序列化模块什么是序列化把内存的数据类型转换成一个特定的格式内容该格式的内容可用于存储或者传输给其他平台使用把内存的数据类型---->序列化----->特......
  • Windows远程桌面(mstsc)不能复制粘贴的解决办法
    在远程Windows服务器中重启“rdpclip.exe”进程即可。1、打开资源管理器,杀掉rdpclip.exe进程;2、开始——》运行,输入:rdpclip.exe,回车重启该进程。3、此时粘贴文件或者......
  • ASP.NET Core依赖注入系统学习教程:容器对构造函数选择的策略
    .NETCore的依赖注入容器之所以能够为应用程序提供服务实例,这都归功于ServiceDescriptor对象提供的服务注册信息。另外,在ServiceDescriptor对象中,还为容器准备了3种提供服......
  • 原生js构造函数及其对象 学习总结
    js构造函数及其对象ES5functionPerson(age){ this.name='张三' this.age=age this.talk=function(){ alert('hello') }}首字母大写构造函数中的thi......
  • 解决fastJson反序列化问题 com.alibaba.fastjson.JSONObject cannot be cast to 的问
    问题描述:个简单的查询逻辑即查询前先从redis取,取到后则进行反序列化。StringresJson=redisService.getString(name);if(StringUtil.isNotEmpty(resJson)){//......
  • 解决csdn 不能复制问题
    F12不能复制代码$("#content_viewspre").css("user-select","text");$("#content_viewsprecode").css("user-select","text");关注才能看代码var article_content=d......
  • FFmpeg学习:frame的复制和拷贝
    实践中经常遇到frame的复制拷贝,特此记录一下;深拷贝连同数据也被复制一份浅拷贝只拷贝参数,具有相同的数据指针相关apiav_frame_ref()【函数原型】点击查看代码......
  • csdn免登陆复制油猴脚本
    安装油猴安装脚本:https://www.tampermonkey.net/可执行脚本:https://greasyfork.org/zh-CN/scripts自己编写一个csdn免登陆复制的脚本://==UserScript==//@name......
  • 拷贝构造函数
    c++中的拷贝构造函数调用时机通常有三种情况1.使用一个已经创建完毕的对象来初始化一个新的对象2.值传递的方式给函数参数传值3.以值方式返回局部对象//情况1classP......