C# DynamicMethod比编译的IL函数慢得多

C# DynamicMethod比编译的IL函数慢得多,c#,cil,il,dynamicmethod,C#,Cil,Il,Dynamicmethod,我编写了一个简单的复制公共属性的对象复制器。 我不明白为什么动态方法比c版本慢很多 持续时间 C#方法:4963 ms 动态法:19924 ms 请注意,在启动秒表之前运行dynamic方法时,持续时间不包括编译阶段。 我在调试和发布模式、x86和x64模式以及VS和命令行中运行它,结果大致相同(动态方法的速度要慢400%) 如果你读两遍,我很高兴。 我最初发布在: 但并没有得到我所希望的所有答案 编辑日期:2012年11月17日15:11: removed the nop removed th

我编写了一个简单的复制公共属性的对象复制器。 我不明白为什么动态方法比c版本慢很多

持续时间

C#方法:4963 ms

动态法:19924 ms

请注意,在启动秒表之前运行dynamic方法时,持续时间不包括编译阶段。 我在调试和发布模式、x86和x64模式以及VS和命令行中运行它,结果大致相同(动态方法的速度要慢400%)

如果你读两遍,我很高兴。 我最初发布在: 但并没有得到我所希望的所有答案

编辑日期:2012年11月17日15:11:

removed the nop
removed the extra ="" which came from I don't where.

这个问题是由
.NET
framework4.0中的更改引起的。我在CodeProject上找到了由用户“”发布的

DynamicMethod
与一个函数关联时,会导致执行时间大大减慢,如果使用
DynamicMethod(string,Type,Type[],bool)
构造函数,就会发生这种情况。与以前的版本相比,.NET4似乎做了更多的安全检查,尽管我对实际发生的情况没有深入了解或解释

DynamicMethod
Type
(通过使用
DynamicMethod(string,Type,Type[],Type,bool)
构造函数相关联;请注意,附加的
Type
值参数“owner”)完全消除了速度惩罚

MSDN上有一些可能相关的注释(如果我能理解的话!):


这有点晚了,但是如果您在所有程序集的.NET 4中设置一些安全属性,并且使用内置的委托类型或具有相同安全属性的委托,您将看到相当大的性能提升

以下是您需要的属性:

[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityTransparent]
[assembly: SecurityRules(SecurityRuleSet.Level2,SkipVerificationInFullTrust=true)]
这实际上似乎有点像一个bug。但是,因为您的代码不会提升安全权限,所以您不会阻止部分受信任的调用方,因此,如果您在完全信任中使用
skipVisibility=true
,调用
Func
委托基本上可以避免几乎所有的权限检查

还有一件事,因为这些是委托,如果您像对待实例方法一样对待它们,即使它们不是委托,也会获得最佳性能。也就是说,始终使用两个
Delegate.CreateDelegate
方法中的一个,该方法接受
firstArgument
参数并向委托添加初始对象引用


考虑使用
skipVisibility=true
构造
DynamicMethod
,但不指定所有者。分配所有者允许您运行。你可以用这个做一些非常糟糕的事情,所以除非你知道你在做什么,否则我会避免它。

你不应该发出“nop”,顺便说一句。你有“nop”的事实表明你处于调试模式。您可以在IDE之外的发布模式下运行它吗?没有“不”这个词?那么你得到了什么时间?什么是
行动
应该意味着什么?这肯定是无效的C#。@JonSkeet如果我从代码中删除所有的
=”
s,它确实会编译,并且它的行为与Pascal描述的一样。@svick:很公平。。。但显然我们不应该这么做。。。(一些空白选项也明显不利于可读性)现在前14行已经被删除…当无法指定所有者参数时,您发布的程序集属性是一个很好的解决方案。好吧,当使用C#表达式树生成方法时就是这种情况。这对我最近提高性能有很大帮助,我唯一关心的是添加这些属性是否会产生我应该担心的副作用?可能,如果您引用的DLL没有正确标记其代码,那么使用安全透明可能会很烦人。@MichaelB关于属性安全性较差的第三方库,有没有一种方法可以通过在托管应用程序的应用程序清单中使用(或其他一些方法)来重新指定或覆盖这些有缺陷或完全不足的规范?我很遗憾不能这么说。我敢打赌,您可能想指定一个所有者,但要小心生成的代码。如果所属类型来自安全位置,则其运行速度应快于非安全代码。Net core没有这个问题。这是有道理的,在调用“安全”委托(而不是常规委托)时会涉及额外的间接级别,请参阅以获取一些信息
removed the nop
removed the extra ="" which came from I don't where.
[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityTransparent]
[assembly: SecurityRules(SecurityRuleSet.Level2,SkipVerificationInFullTrust=true)]