C#深拷贝效率对比

对于浅拷贝和深拷贝,前面的文章已经说明了。

C#浅拷贝和深拷贝数据-CSDN博客

        本篇说一下,深拷贝的效率问题,效率一直是程序追求的,效率越高肯定越好,有时候功能是实现了,但是运行以及处理数据的效率非常低,此时就让人很头疼,当你知道了如何提高效率的时候,在你实现功能的时候,就已经考虑进去了,而不是先把功能做好,后期再优化(当然这种模式覆盖大部分人的开发习惯)。

测试1:

使用共同的数据结构和100W数量,分别对比4种深拷贝的效率问题。

1.反射

耗时:3465 

2.JSON字符串序列化

耗时: 7095

3.表达式树

耗时:396 

4.AutoMapper

耗时:682 

结论:
表达式树>AutoMapper>反射>JSON。如果数据结构非常复杂而且多,那么就使用表达式树。 

测试2:

使用共同的数据结构和10W数量,分别对比4种深拷贝的效率问题。

1.反射

耗时:498

2.JSON字符串序列化

耗时: 1072

3.表达式树

耗时:243

4.AutoMapper

耗时:268

结论:

表达式树>AutoMapper>反射>JSON

代码:


using AutoMapper;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using static WpfApp4.MainWindow;
using Expression = System.Linq.Expressions.Expression;namespace WpfApp4
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();Stopwatch sw = new Stopwatch();sw.Start();var config = new MapperConfiguration(cfg => cfg.CreateMap<TestData1, TestData1>());//映射配置for (int i = 0; i < 10_0000; i++){TestData3 testData3 = new TestData3();testData3.ID = 3 + i;testData3.D1 = "3.1" + i.ToString();testData3.D2 = "3.2" + i.ToString();TestData2 testData2 = new TestData2();testData2.ID = 2 + i;testData2.D1 = "2.1" + i.ToString();testData2.D2 = "2.2" + i.ToString();testData2.testData3 = testData3;TestData1 testData1 = new TestData1();testData1.ID = 1 + i;testData1.D1 = "1.1" + i.ToString();testData1.D2 = "1.2" + i.ToString();testData1.testData2 = testData2;//反射效率//var test2 = DeepCopyWithReflection(testData1);//JSON字符串序列化效率//var test3 = JsonConvert.DeserializeObject<TestData1>(JsonConvert.SerializeObject(testData1));//表达式树效率//var test4 = TransExp<TestData1, TestData1>.Trans(testData1);//AutoMapper效率var test5 = config.CreateMapper().Map<TestData1>(testData1);}double count = sw.Elapsed.TotalMilliseconds;sw.Stop();int a = 0;}/// <summary>/// 利用反射实现深拷贝/// </summary>/// <typeparam name="T"></typeparam>/// <param name="obj"></param>/// <returns></returns>public static T DeepCopyWithReflection<T>(T obj){Type type = obj.GetType();// 如果是字符串或值类型则直接返回if (obj is string || type.IsValueType) return obj;// 如果是数组if (type.IsArray){Type elementType = Type.GetType(type.FullName.Replace("[]", string.Empty));var array = obj as Array;Array copied = Array.CreateInstance(elementType, array.Length);for (int i = 0; i < array.Length; i++){copied.SetValue(DeepCopyWithReflection(array.GetValue(i)), i);}return (T)Convert.ChangeType(copied, obj.GetType());}object retval = Activator.CreateInstance(obj.GetType());PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic| BindingFlags.Instance | BindingFlags.Static);foreach (var property in properties){var propertyValue = property.GetValue(obj, null);if (propertyValue == null)continue;property.SetValue(retval, DeepCopyWithReflection(propertyValue), null);}return (T)retval;}/// <summary>/// 表达式树/// </summary>/// <typeparam name="TIn"></typeparam>/// <typeparam name="TOut"></typeparam>public static class TransExp<TIn, TOut>{private static readonly Func<TIn, TOut> cache = GetFunc();private static Func<TIn, TOut> GetFunc(){ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");List<MemberBinding> memberBindingList = new List<MemberBinding>();foreach (var item in typeof(TOut).GetProperties()){if (!item.CanWrite) continue;MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));MemberBinding memberBinding = Expression.Bind(item, property);memberBindingList.Add(memberBinding);}MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] { parameterExpression });return lambda.Compile();}public static TOut Trans(TIn tIn){return cache(tIn);}}}
}

总结:总的来说,数据量在100W的时候,差距还是很明显的,建议使用表达式树,在10W数量的时候,表达式树和AutoMapper差距已经不是很大了,数据量再小的话,预计差别就更少了,具体使用,还是看程序的数据在什么量级。

源码:

https://download.csdn.net/download/u012563853/88637623

本文来源:

C#深拷贝效率对比-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/285625.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu 18.04配置NFS服务器以及配置时遇到NFS问题

1.安装相关软件 sudo apt-get install nfs-kernel-server sudo apt-get install nfs-common 2.配置共享目录 2.1修改exports文件 sudo vi /etc/exports在最后添加如下并保存退出 /home/xiaowu/nfs 192.168.31*(rw,sync,no_root_squash,no_subtree_check) /home/xiaowu/nfs…

【密码学】群的证明(习题)

0.前置知识 1.习题 记录一次密码学作业~群的判定 2.求解

〖大前端 - 基础入门三大核心之JS篇(57)〗- 继承

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

骨传导耳机和气传导耳机有什么区别?谁更值得入手?

先说答案&#xff0c;骨传导耳机和气传导耳机的佩戴方式和传声方式不同&#xff0c;并且骨传导耳机相比于气传导耳机更值得入手。 一、骨传导耳机和气传导耳机有什么区别 1、佩戴方式不同 骨传导耳机采用一体式耳挂佩戴或耳夹式佩戴&#xff0c;气传导耳机采用分体式耳挂设计…

采样率8kHz~96kHz单端输入ADC芯片CJC1808

音频模/数转换器是一种用于将模拟音频信号转换成数字信号的设备&#xff0c;可以提供高质量的音频转换功能&#xff1b;被广泛应用于录音室、数字音频处理、混音、模拟音频处理等应用中&#xff1b;是当今数字音频处理中不可或缺的一部分。 ADC芯片可以提供宽频带的模拟输入&a…

SpringCloud微服务 【实用篇】| Docker镜像、容器、数据卷操作

目录 一&#xff1a;Docker基本操作 1. 镜像操作 镜像相关命令 2. 容器操作 容器相关命令 3. 数据卷&#xff08;容器数据管理&#xff09; 数据卷 操作数据卷 挂载数据卷 挂载的方式区别 前些天突然发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0…

如何利用CHAT写C程序?

问CHAT&#xff1a;用c语言编写在二维字符数组中查找某个字符串 CHAT回复&#xff1a;以下是一个简单的C程序&#xff0c;它将在二维字符数组中查找特定的字符串。 c #include <stdio.h> #include <string.h> void search(char arr[100][100], int r, char* str) …

Java泛型(1)

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

xxl-job 分布式调度学习笔记

1.概述 1.1什么是任务调度 业务场景&#xff1a; 上午10点&#xff0c;下午2点发放一批优惠券 银行系统需要在信用卡到期还款日的前三天进行短信提醒 财务系统需要在每天凌晨0:10分结算前一天的财务数据&#xff0c;统计汇总 不同系统间的数据需要保持一致&#xff0c;这时…

构建健康中国:医保支付购药系统的技术实现

在数字化时代&#xff0c;医保支付购药系统的技术实现成为医疗保障体系不可或缺的一环。通过整合医疗资源、优化服务流程&#xff0c;这一系统为患者提供了更便捷、高效的医疗服务。本文将深入探讨医保支付购药系统的技术架构与实现方法。 1. 技术架构概述 医保支付购药系统…

利用台阶仪测量薄膜厚度的方法和技巧

在薄膜制备过程中&#xff0c;薄膜厚度是一个至关重要的参数&#xff0c;直接影响薄膜的性能和应用。为了准确测量薄膜厚度&#xff0c;研究者广泛使用台阶仪&#xff0c;这是一种方便、直接、准确的测量方法。本文将介绍如何利用台阶仪进行薄膜厚度测量的方法和技巧。 选择合…

谷歌Chrome浏览器无法安装插件的解决方法

Google Chrome是一款由Google公司开发的网页浏览器&#xff0c;该浏览器基于其他开源软件撰写&#xff0c;包括WebKit&#xff0c;目标是提升稳定性、速度和安全性&#xff0c;并创造出简单且有效率的使用者界面。使用谷歌浏览器安装扩展插件的时候有时会遇到无法安装问题 解决…