先看结果
所以复制构造函数优于序列化和反序列化
代码如下:
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; } } }
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 对象与内存拷贝、交换、克隆 } }