C# LambdaExpression.Compile和Delegate.CreateDelegate之间的差异

C# LambdaExpression.Compile和Delegate.CreateDelegate之间的差异,c#,.net,lambda,delegates,C#,.net,Lambda,Delegates,在优化反射调用的过程中,我正在尝试使用并将我的MethodInfos转换为更快的委托 基于,我期望LambdaExpression.Compile的性能会显著提高,因为它将为方法调用生成实际的MSIL——接近直接方法调用的某个地方 然而,在基准测试之后,我注意到这两种技术的性能大致相同 我的假设是,调用使用LambdaExpression.Compile创建的委托时所产生的开销是由于委托本身的使用。为了确认这一点,我创建了另一个基准测试,在该基准测试中,我手动创建了直接调用该方法的委托,并且它具

在优化反射调用的过程中,我正在尝试使用并将我的
MethodInfo
s转换为更快的委托

基于,我期望
LambdaExpression.Compile
的性能会显著提高,因为它将为方法调用生成实际的MSIL——接近直接方法调用的某个地方

然而,在基准测试之后,我注意到这两种技术的性能大致相同

我的假设是,调用使用
LambdaExpression.Compile创建的委托时所产生的开销是由于委托本身的使用。为了确认这一点,我创建了另一个基准测试,在该基准测试中,我手动创建了直接调用该方法的委托,并且它具有类似的性能

因此,我的问题是:由
LambdaExpression.Compile
delegate.CreateDelegate
生成的委托对象有什么不同吗

我正在寻找关于这两种方法之间差异的理论答案,因此我将不讨论实现细节,但以下是实现的jist:

  • 代表:,作者:Jon Skeet
  • 对于lambda表达式:使用
    Expression.Call
    Expression.Parameter
    Expression.lambda
    Expression.Compile

Delegate.CreateDelegate和LambdaExpression.Compile之间存在差异,事实上,第二种方法做得更多,在特定条件下更有效

当您手动调用Delegate.CreateDelegate时,您可以使用一些带有目标值的重载来调用它,但在某些情况下,例如静态方法,您没有目标值

在后台,当您并没有目标值时,将使用生成的方法创建委托,以便在跳入实际方法之前在堆栈中弹出无用的值。您可以使用watcher观察它:委托具有InPtr和InPtrAux

当IntPtrAux被分配给有效指针时,这意味着在弹出句柄并跳转到IntPtrAux之前调用InPtr。这就是为什么与静态方法相比,为实例方法(句柄是“this”)创建的委托的委托效率更高


在lambda expression compile生成委托的过程中,始终使用Target(用于关闭)并避免调用/跳转IntPtrAux,这通常是有效的。

对于投票关闭的人;要不要评论一下?我不明白为什么LambdaExpression委托应该更快。是的,它会生成msil,但是Delegate.CreateDelegate会为已经存在的方法创建委托,并且已经生成了msil,那么有什么区别呢?这正是我的问题。在IL级别,调用通过
delegate.CreateDelegate
创建的委托与调用通过
LambdaExpression.Compile
创建的委托之间是否存在差异?(即使这个差异很小)一个是委托(函数的引用),另一个是委托。他们之间没有区别。所有的区别都在于这些代表所指向的功能。