原文:2019-11-29-C#-性能分析-反射-VS-配置文件-VS-预编译

title author date CreateTime categories
C# 性能分析 反射 VS 配置文件 VS 预编译
lindexi
2019-11-29 10:13:17 +0800
2018-10-15 20:48:40 +0800
C# 性能测试

本文分析在 C# 中使用反射和配置文件和预编译做注入的性能,本文的数据是为预编译框架,开发高性能应用 - 课程 - 微软技术暨生态大会 2018 - walterlv提供

本文通过代码生成工具,使用C# 标准性能测试拿到三个不同的方法的性能

先来介绍一个程序的构成,这个程序里面有 1000 个类,这些类表示需要注入的类,每个类的代码大概都是这样

namespace LecuryouWuruhempa
{
[CelkaturjairQelofe]
class 类名
{
public string Foo { get; set; }
}
}

所有的类只有类名不相同,注入类的方法本文使用三个不同的方法,第一个就是预编译的方法。这里的预编译的方法就是在编译的时候,通过 Roslyn 拿到程序集里的所有类,和正常写代码一样,写出所有的类的创建和注入。

测试的类里通过一个 List<object> 作为注入的输入,也就是通过任意的方式将对应的类创建出来,放进这个列表就是注入完成。

使用预编译的方法就像直接在代码里写 new Foo() 一样

而通过配置文件的方法实际也是反射的方法,只是少了反射整个程序集找到对应的类的过程

通过读取配置文件拿到了程序集需要注入的所有类的类名,然后通过反射的方法拿到对应的 Type 再通过 Type 拿到构造函数,创建对象加入列表。本文为了防止因为读取配置文件让时间都在磁盘就直接写出了程序集的所有类

而反射的方法是反射程序集,通过判断类的 Attitude 也就是上面代码的 CelkaturjairQelofe 特性,如果一个类有这个特性,那么这个类就是需要注入的类,通过反射创建加入列表。

反射的代码都很简单,先看一下测试的数据

Method Mean Error StdDev Median Scaled ScaledSD
预编译 28.20 us 0.3970 us 0.3713 us 28.16 us 1.00 0.00
配置文件 2,125.77 us 44.3371 us 121.3722 us 2,074.70 us 75.39 4.39
反射特定的类 3,141.09 us 47.0754 us 41.7311 us 3,146.11 us 111.40 2.01

预编译如果使用委托创建,测试数据会比直接 new 的慢很多

Method Mean Error StdDev Scaled ScaledSD
预编译-new 28.48 us 0.3682 us 0.3445 us 1.00 0.00
预编译-委托创建 61.55 us 1.1327 us 1.0595 us 2.16 0.04
配置文件 2,098.50 us 40.6163 us 48.3508 us 73.70 1.87
反射特定的类 3,236.56 us 63.3132 us 126.4434 us 113.67 4.59

我通过设置了基线是预编译,可以看到通过配置文件创建的方式比预编译慢 75 倍,而通过反射特定的类是慢 100 多倍

其他测试请看 C# 直接创建多个类和使用反射创建类的性能

C# 程序内的类数量对程序启动的影响

整个测试的工程我打包放在下面,这个工程的创建代码很简单,我也直接放在下面

测试的工程 C# 性能分析 反射 VS 配置文件 VS 预编译-CSDN下载

如果觉得我的数据很诡异,那么请自己运行一下

创建工程的代码不包括创建测试的工程的框架,测试项目的框架很简单,只需要创建一个空白的控制台项目,在这个控制台项目安装 BenchmarkDotNet 打开 Program 添加下面代码

using BenchmarkDotNet.Running;

    public class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<SawstoJouweaxo>(); }
}

通过运行 ReecelnaxeaDrasilouhalLaigeci 方法就可以在运行的文件夹找到创建的文件夹,将这个文件夹复制到测试的工程就可以

{% raw %}

        private static void ReecelnaxeaDrasilouhalLaigeci()
{
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
{{
[CelkaturjairQelofe]
class {pereviCirsir}
{{
public string Foo {{ get; set; }}
}}
}}"; File.WriteAllText(Path.Combine(jisqeCorenerairTurpalhee.FullName, pereviCirsir + ".cs"), nemhaSibemnoosa);
} var celkaturjairQelofeAttribute = @"using System; namespace LecuryouWuruhempa
{
class CelkaturjairQelofeAttribute : Attribute
{ }
}";
File.WriteAllText(Path.Combine(jisqeCorenerairTurpalhee.FullName, "CelkaturjairQelofeAttribute.cs"), celkaturjairQelofeAttribute); var memtichooBowbosir = new StringBuilder();
foreach (var temp in direhelXideNa)
{
memtichooBowbosir.Append($" _jooyiSouse.Add(new {temp}());\r\n");
} var sowastowVaiyoujall = $@"
[Benchmark(Baseline = true, Description = ""预编译"")]
public void WeejujeGaljouPemhu()
{{
_jooyiSouse.Clear(); {memtichooBowbosir.ToString()}
}}
"; memtichooBowbosir.Clear();
memtichooBowbosir.Append($@" List<string> jeesareMewheehowBistawHorbatall = new List<string>()
{{
"); foreach (var temp in direhelXideNa)
{
memtichooBowbosir.Append($"\"{temp}\", ");
memtichooBowbosir.Append("\r\n");
} memtichooBowbosir.Append(" };"); var sifurDassalcha = $@"
[Benchmark(Description = ""配置文件"")]
public void KonejoDewee()
{{
Type cajeceKisorkeBairdi; ConstructorInfo wimoDasrugowfo;
object relrorlelJosurpo;
_jooyiSouse.Clear(); {memtichooBowbosir.ToString()} foreach (var temp in jeesareMewheehowBistawHorbatall)
{{
cajeceKisorkeBairdi = Type.GetType(""LecuryouWuruhempa."" + temp);
wimoDasrugowfo = cajeceKisorkeBairdi.GetConstructor(Type.EmptyTypes);
relrorlelJosurpo = wimoDasrugowfo.Invoke(null);
_jooyiSouse.Add(relrorlelJosurpo); }} }}"; var stoomairHem = @"
[Benchmark(Description = ""反射"")]
public void TirjeTuxemsowwherLaralJunoo()
{
_jooyiSouse.Clear(); var bermartaPallnirhi = Assembly.GetExecutingAssembly(); foreach (var temp in bermartaPallnirhi.GetTypes())
{
var wimoDasrugowfo = temp.GetConstructor(Type.EmptyTypes);
var relrorlelJosurpo = wimoDasrugowfo.Invoke(null);
_jooyiSouse.Add(relrorlelJosurpo);
}
}"; stoomairHem = ""; memtichooBowbosir.Clear(); memtichooBowbosir.Append(@" List<Func<object>> lairchurBirchalrotro = new List<Func<object>>()
{
"); foreach (var temp in direhelXideNa)
{
memtichooBowbosir.Append($" () => new {temp}(),");
memtichooBowbosir.Append("\r\n");
} memtichooBowbosir.Append(" };"); stoomairHem = $@"
[Benchmark(Description = ""委托创建"")]
public void LemjobesuDijisleci()
{{ _jooyiSouse.Clear(); {memtichooBowbosir.ToString()} foreach (var temp in lairchurBirchalrotro)
{{
_jooyiSouse.Add(temp());
}}
}}"; var drairdreBibearnou = @"
[Benchmark(Description = ""反射特定的类"")]
public void SasesoJirkoukistiCowqu()
{
_jooyiSouse.Clear(); var bermartaPallnirhi = Assembly.GetExecutingAssembly(); foreach (var temp in bermartaPallnirhi.GetTypes().Where(temp=> temp.GetCustomAttribute<CelkaturjairQelofeAttribute>() != null))
{
var wimoDasrugowfo = temp.GetConstructor(Type.EmptyTypes);
var relrorlelJosurpo = wimoDasrugowfo.Invoke(null);
_jooyiSouse.Add(relrorlelJosurpo);
}
}"; var whelvejawTinaw = $@"using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes; namespace LecuryouWuruhempa
{{
public class SawstoJouweaxo
{{ {sowastowVaiyoujall} {sifurDassalcha} {stoomairHem} {drairdreBibearnou} private List<object> _jooyiSouse = new List<object>(); }}
}}"; File.WriteAllText(Path.Combine(jisqeCorenerairTurpalhee.FullName, "SawstoJouweaxo.cs"), whelvejawTinaw);
}

{% endraw %}

2019-11-29-C#-性能分析-反射-VS-配置文件-VS-预编译的更多相关文章

  1. C# 性能分析 反射 VS 配置文件 VS 预编译

    本文分析在 C# 中使用反射和配置文件和预编译做注入的性能,本文的数据是为预编译框架,开发高性能应用 - 课程 - 微软技术暨生态大会 2018 - walterlv提供 本文通过代码生成工具,使用C ...

  2. 2019-8-31-C#-性能分析-反射-VS-配置文件-VS-预编译

    title author date CreateTime categories C# 性能分析 反射 VS 配置文件 VS 预编译 lindexi 2019-08-31 16:55:58 +0800 ...

  3. 2019.11.29 Mysql的数据操作

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

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

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

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

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

  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. 11个Visual Studio代码性能分析工具

    软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行代码分析和 ...

  9. .NET 11 个 Visual Studio 代码性能分析工具

    原文地址 软件开发中的性能优化对程序员来说是一个非常重要的问题.一个小问题可能成为一个大的系统的瓶颈.但是对于程序员来说,通过自身去优化代码是十分困难的.幸运的是,有一些非常棒的工具可以帮助程序员进行 ...

随机推荐

  1. [Linux] nginx的try_files指令实现隐藏index.php的重写

    1.nginx的try_files指令 ,核心功能是替代rewrite,并且比rewrite更强大的是可以按顺序查找文件是否存在,如果文件都找不到才会执行最后的重定向解决的问题是,如果一个网站的部署是 ...

  2. 目标检测论文解读1——Rich feature hierarchies for accurate object detection and semantic segmentation

    背景 在2012 Imagenet LSVRC比赛中,Alexnet以15.3%的top-5 错误率轻松拔得头筹(第二名top-5错误率为26.2%).由此,ConvNet的潜力受到广泛认可,一炮而红 ...

  3. dga model train and test code

    # _*_coding:UTF-8_*_ import operator import tldextract import random import pickle import os import ...

  4. Dmidecode命令

    Dmidecode简介 DMI (Desktop Management Interface, DMI)就是帮助收集电脑系统信息的管理系统,DMI信息的收集必须在严格遵照SMBIOS规范的前提下进行. ...

  5. shell 之for循环几种写法

    参见博客 http://blog.csdn.net/babyfish13/article/details/52981110 ,此博客写的非常清晰明了.

  6. Tableau可视化操作

    1.地图显示 1.修改地理角色:“省份” 2.双击省份—绘制地图 3.显示销售额和利润额的情况—销售额(大小)+利润额(颜色) 4.修改显示颜色:两种方式 第一种方式:双击右边利润额图例— 第二种方式 ...

  7. div层的滑入滑出实例

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"><head runat=&quo ...

  8. 解决PEnetwork启动的时候提示"An error occured while starting the "TCP/IP Registry Compatibility" Service (2)!"程序将立即退出的问题

    解决PEnetwork启动的时候提示"An error occured while starting the "TCP/IP Registry Compatibility" ...

  9. Linux性能优化实战学习笔记:第四十讲

    一.上节回顾 上一节,我们学习了碰到分布式拒绝服务(DDoS)的缓解方法.简单回顾一下,DDoS利用大量的伪造请求,导致目标服务要耗费大量资源,来处理这些无效请求,进而无法正常响应正常用户的请求. 由 ...

  10. PowerShell常用命令及美化(现代化的CMD)

    PowerShell可谓现代终端,是微软用来替代古老的CMD的. PowerShell拥有面向对象的思想,非常方便. 常用命令 下载文件(此处以install.ps1文件为例) $client = n ...