c#如何使用反射去创建一个委托_C# 直接创建多个类和使用反射创建类的性能

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

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

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

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

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

MethodMeanErrorStdDevMedian直接创建15.90 us0.3173 us0.3116 us15.81 us

Activator 创建481.28 us9.3487 us9.6004 us477.99 us

ConstructorInfo 创建2,179.59 us84.8502 us242.0823 us2,084.09 us

bd8b24e0f9ce682fa13d4bd22bbfd31c.png

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

创建垃圾代码的方法

private static void KicuJoosayjersere()

{

var terebawbemTitirear = new WhairchooHerdo();

List direhelXideNa=new List();

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);

}

这里的 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();

}

创建之后可以看到

bd8b24e0f9ce682fa13d4bd22bbfd31c.png

然后将这个文件夹导入到一个新创建的项目,要求这个项目是 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();

}

}

}

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

MethodMeanErrorStdDevWeejujeGaljouPemhu16.11 us0.3217 us0.3160 us

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

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

MethodMeanErrorStdDevWeejujeGaljouPemhu15.68 us0.2810 us0.2628 us

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

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

两个不同的创建方法是

Activator.CreateInstance();

Type cajeceKisorkeBairdi;

ConstructorInfo wimoDasrugowfo;

object relrorlelJosurpo;

cajeceKisorkeBairdi = Type.GetType("命名空间." + nameof(类型));

wimoDasrugowfo = cajeceKisorkeBairdi.GetConstructor(Type.EmptyTypes);

relrorlelJosurpo = wimoDasrugowfo.Invoke(null);

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

MethodMeanErrorStdDevMedian直接创建15.90 us0.3173 us0.3116 us15.81 us

Activator 创建481.28 us9.3487 us9.6004 us477.99 us

ConstructorInfo 创建2,179.59 us84.8502 us242.0823 us2,084.09 us

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

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

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

private static void BenediZayle()

{

var terebawbemTitirear = new WhairchooHerdo();

List direhelXideNa = new List();

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();\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);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值