原文:2019-11-29-C#-直接创建多个类和使用反射创建类的性能

title author date CreateTime categories
C# 直接创建多个类和使用反射创建类的性能
lindexi
2019-11-29 10:13:14 +0800
2018-10-12 11:24:21 +0800
C# 性能测试

本文告诉大家我对比的使用直接创建多个类和使用反射创建多个类的性能

在上一篇 C# 程序内的类数量对程序启动的影响 的基础上,继续做实验

现在创建 1000 个类和一个测试使用的类,测试方法请看 C# 标准性能测试

虽然一开始就知道了反射的性能比较差,但是究竟有多差,在创建对象的时候的差异有多少?

反射创建对象的方法有很多个,本文就只测试其中的两个,一个是通过 Activator 的方式创建,另一个是通过 ConstructorInfo 的方式创建

本文通过实际测试发现了使用 Activator 创建比直接创建慢 30 倍,通过 ConstructorInfo 创建比直接创建慢 137 倍

Method Mean Error StdDev Median
直接创建 15.90 us 0.3173 us 0.3116 us 15.81 us
Activator 创建 481.28 us 9.3487 us 9.6004 us 477.99 us
ConstructorInfo 创建 2,179.59 us 84.8502 us 242.0823 us 2,084.09 us

而在调用方法的速度请看图片,详细请看.NET Core/Framework 创建委托以大幅度提高反射调用的性能 - walterlv

如果关心这个结论是如何计算出来的,或者你也想使用 1000 个类,那么请继续翻到下一页

创建垃圾代码的方法

{% raw %}

       private static void KicuJoosayjersere()
{
var terebawbemTitirear = new WhairchooHerdo(); List<string> direhelXideNa=new List<string>(); var jisqeCorenerairTurpalhee = new DirectoryInfo("MerelihikeLouseafoopu"); jisqeCorenerairTurpalhee.Create(); for (int i = 0; i < 1000; i++)
{
var pereviCirsir = terebawbemTitirear.LemgeDowbovou(); direhelXideNa.Add(pereviCirsir); var nemhaSibemnoosa = $@"
using System;
using System.Collections.Generic;
using System.Text; namespace LecuryouWuruhempa
{{
class {pereviCirsir}
{{
public string Foo {{ get; set; }}
}}
}}"; File.WriteAllText(Path.Combine(jisqeCorenerairTurpalhee.FullName, pereviCirsir + ".cs"), nemhaSibemnoosa);
} var memtichooBowbosir=new StringBuilder();
foreach (var temp in direhelXideNa)
{
memtichooBowbosir.Append($" new {temp}();\r\n");
} var whelvejawTinaw = $@"using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; namespace LecuryouWuruhempa
{{
public class SawstoJouweaxo
{{
[Benchmark]
public void WeejujeGaljouPemhu()
{{
{memtichooBowbosir.ToString()}
}}
}}
}}"; File.WriteAllText(Path.Combine(jisqeCorenerairTurpalhee.FullName, "SawstoJouweaxo.cs"), whelvejawTinaw);
}

{% endraw %}

这里的 WhairchooHerdo 类就是用来创建类的名

    class WhairchooHerdo
{
public string LemgeDowbovou()
{
var zarwallsayKeesar = (char) _ran.Next('A', 'Z' + 1);
var lardurDairlel = new StringBuilder();
lardurDairlel.Append(zarwallsayKeesar);
for (int i = 0; i < 5; i++)
{
lardurDairlel.Append((char)_ran.Next('a', 'z'));
} return lardurDairlel.ToString();
} private Random _ran = new Random();
}

创建之后可以看到

然后将这个文件夹导入到一个新创建的项目,要求这个项目是 dotnet Framework 4.6 以上,使用下面代码做测试

using System;
using System.Diagnostics;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.InProcess; namespace LecuryouWuruhempa
{
public class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<SawstoJouweaxo>();
}
}
}

这时运行一下,可以看到一次运行只需要 16us 十分快

Method Mean Error StdDev
WeejujeGaljouPemhu 16.11 us 0.3217 us 0.3160 us

也许大家会说,这个方法是因为被优化了,现在添加 MethodImpl 禁止优化,请看win10 uwp 禁止编译器优化代码

运行的可以看到几乎没有影响

Method Mean Error StdDev
WeejujeGaljouPemhu 15.68 us 0.2810 us 0.2628 us

下面来对比两个不同的反射的创建方式和直接创建的速度

代码创建的方式请看文章最后

两个不同的创建方法是

Activator.CreateInstance<类型>();

            Type cajeceKisorkeBairdi;

            ConstructorInfo wimoDasrugowfo;
object relrorlelJosurpo; cajeceKisorkeBairdi = Type.GetType("命名空间." + nameof(类型));
wimoDasrugowfo = cajeceKisorkeBairdi.GetConstructor(Type.EmptyTypes);
relrorlelJosurpo = wimoDasrugowfo.Invoke(null);

只是创建的对象有 1000 个,运行一下就可以看到文章最上面的数据

Method Mean Error StdDev Median
直接创建 15.90 us 0.3173 us 0.3116 us 15.81 us
Activator 创建 481.28 us 9.3487 us 9.6004 us 477.99 us
ConstructorInfo 创建 2,179.59 us 84.8502 us 242.0823 us 2,084.09 us

从上面的代码可以看到,反射还是很伤性能,因为这个数值在不同的设备有不同的大小,但是数值之间的比例都是差不多

可以计算出 Activator 创建比直接创建慢 30 倍,通过 ConstructorInfo 创建比直接创建慢 137 倍

创建对比直接创建和两个不同的反射方法的代码

{% raw %}

       private static void BenediZayle()
{
var terebawbemTitirear = new WhairchooHerdo(); List<string> direhelXideNa = new List<string>(); var jisqeCorenerairTurpalhee = new DirectoryInfo("MerelihikeLouseafoopu"); jisqeCorenerairTurpalhee.Create(); for (int i = 0; i < 1000; i++)
{
var pereviCirsir = terebawbemTitirear.LemgeDowbovou(); direhelXideNa.Add(pereviCirsir); var nemhaSibemnoosa = $@"
using System;
using System.Collections.Generic;
using System.Text; namespace LecuryouWuruhempa
{{
class {pereviCirsir}
{{
public string Foo {{ get; set; }}
}}
}}"; File.WriteAllText(Path.Combine(jisqeCorenerairTurpalhee.FullName, pereviCirsir + ".cs"), nemhaSibemnoosa);
} var memtichooBowbosir = new StringBuilder();
foreach (var temp in direhelXideNa)
{
memtichooBowbosir.Append($" new {temp}();\r\n");
} var sowastowVaiyoujall = $@"
[Benchmark]
public void WeejujeGaljouPemhu()
{{
{memtichooBowbosir.ToString()}
}}
"; memtichooBowbosir.Clear(); foreach (var temp in direhelXideNa)
{
memtichooBowbosir.Append($" Activator.CreateInstance<{temp}>();\r\n");
} var learhuseRasel = $@"
[Benchmark]
[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
public void BowhempuWurrofe()
{{
{memtichooBowbosir.ToString()}
}}
"; memtichooBowbosir.Clear(); foreach (var temp in direhelXideNa)
{
memtichooBowbosir.Append(
$" cajeceKisorkeBairdi = Type.GetType(\"LecuryouWuruhempa.\" + nameof({temp}));\r\n");
memtichooBowbosir.Append(@"
wimoDasrugowfo = cajeceKisorkeBairdi.GetConstructor(Type.EmptyTypes);
relrorlelJosurpo = wimoDasrugowfo.Invoke(null);
"); } var sifurDassalcha = $@"
[Benchmark]
[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
public void KonejoDewee()
{{
Type cajeceKisorkeBairdi; ConstructorInfo wimoDasrugowfo;
object relrorlelJosurpo; {memtichooBowbosir.ToString()} }}"; var whelvejawTinaw = $@"using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; namespace LecuryouWuruhempa
{{
public class SawstoJouweaxo
{{
{sowastowVaiyoujall} {learhuseRasel} {sifurDassalcha} }}
}}"; File.WriteAllText(Path.Combine(jisqeCorenerairTurpalhee.FullName, "SawstoJouweaxo.cs"), whelvejawTinaw);
}

{% endraw %}

2019-11-29-C#-直接创建多个类和使用反射创建类的性能的更多相关文章

  1. C# 直接创建多个类和使用反射创建类的性能

    原文:C# 直接创建多个类和使用反射创建类的性能 本文告诉大家我对比的使用直接创建多个类和使用反射创建多个类的性能 在上一篇 C# 程序内的类数量对程序启动的影响 的基础上,继续做实验 现在创建 10 ...

  2. 2019-8-31-C#-直接创建多个类和使用反射创建类的性能

    title author date CreateTime categories C# 直接创建多个类和使用反射创建类的性能 lindexi 2019-08-31 16:55:58 +0800 2018 ...

  3. 2019.11.29 SAP SMTP郵件服務器配置 發送端 QQ郵箱

    今天群裏的小夥伴問了如何配置郵件的問題,隨自己在sap裏面配置了一個 1.    RZ10配置參數 a)       参数配置前,先导入激活版本 执行完毕后返回 b)      输入参数文件DEFAU ...

  4. pycharm+anaconda在Mac上的配置方法 2019.11.29

    内心os: 听人说,写blog是加分项,那他就不是浪费时间的事儿了呗 毕竟自己菜还是留下来东西来自己欣赏吧 Mac小电脑上进行python数据开发环境的配置 首先下载Anaconda,一个超好用的数据 ...

  5. 2019.11.29 Mysql的数据操作

    为名为name的表增加数据(插入所有字段) insert into name values(1,‘张三’,‘男’,20); 为名为name的表增加数据(插入部分字段) insert into name ...

  6. Supervision meeting notes 2019/11/29

    topic 分支:  1. subgraph/subsequence mining Wang Jin, routine behavior/ motif. Philippe Fournier Viger ...

  7. EOJ Monthly 2019.11 E. 数学题(莫比乌斯反演+杜教筛+拉格朗日插值)

    传送门 题意: 统计\(k\)元组个数\((a_1,a_2,\cdots,a_n),1\leq a_i\leq n\)使得\(gcd(a_1,a_2,\cdots,a_k,n)=1\). 定义\(f( ...

  8. 黑盒测试实践--Day5 11.29

    黑盒测试实践--Day5 11.29 今天完成任务情况: 分析系统需求,完成场景用例设计 小组负责测试的同学学习安装自动测试工具--QTP,并在线学习操作 小黄 今天的任务是完成场景测试用例的设计.在 ...

  9. Alpha冲刺(6/10)——2019.4.29

    所属课程 软件工程1916|W(福州大学) 作业要求 Alpha冲刺(6/10)--2019.4.29 团队名称 待就业六人组 1.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪 ...

随机推荐

  1. Scrum 冲刺第一篇

      我们是这次稳了队,队员分别是温治乾,黄思扬,莫少政,余泽端,江海灵 码云地址为:https://gitee.com/sixers/activityWall-Web 一.各个成员在 Alpha 阶段 ...

  2. 我的第一次diy装机记录——小白的配置篇

    工欲善其事,必先利其器 相对于IT人来说,电脑是个好东西,应该是第二个除了手机陪伴我们最长的东西.今年4月份来的杭州,留下了那款陪我征战4年的笔记本,没有电脑,下班后的夜晚索然无味,身心的需求也日渐强 ...

  3. bootstrap基础样式学习(二)——栅格

    (1)最外层必须使用容器 div.container或 div.container-fluid (2)容器可以放置任何内容,若想使用栅格系统必须用 div.row div.container > ...

  4. ZKEACMS 无法运行问题汇总

    前言 如果你还不知道ZKEACMS,不妨先了解一下. ASP.NET MVC 开源建站系统 ZKEACMS 推荐,从此网站“拼”起来 官方地址:http://www.zkea.net/zkeacms ...

  5. HTTPS中的加密验证部分理论

    为了加深自己对于https加密这一块的映象,决定写出来试试 就是在http层下面加了一个ssl层, 服务器将自己的公钥发送给证书机构,申请证书,证书机构首先会验证个服务器是否合法,线上或者线下,然后用 ...

  6. appium---app输入中文

    在app自动化的过程中,都会遇到输入中文的问题,今天总结下app自动化如何输入中文 app输入中文 在启动app的时候在参数里面添加unicodeKeyboard和resetKeyboard后,运行代 ...

  7. 跟着ALEX 学python day3集合 文件操作 函数和函数式编程 内置函数

    声明 : 文档内容学习于 http://www.cnblogs.com/xiaozhiqi/  一. 集合 集合是一个无序的,不重复的数据组合,主要作用如下 1.去重 把一个列表变成集合 ,就自动去重 ...

  8. Spring Boot 引入外部yml配置文件

    当需要在springboot中引用其他的yml文件时,需要在application.yml里配置 spring:     profiles:         include: email,xmyb   ...

  9. openlayers绘制点,线,圆等

    由于我的业务需求是可以在底图上进行一些操作,比如绘制电子围栏等功能,于是需要使用openlayers中的画笔功能,接下来开始一波操作 还是上一篇的html页面, 直接上代码 <!doctype ...

  10. The 13th Chinese Northeast Collegiate Programming Contest

    题解: solution Code: A. Apple Business #include<cstdio> #include<algorithm> #include<ve ...