2008-08-14 23 views
20

给定一个空的方法体,JIT会优化出这个调用(我知道C#编译器不会)。我将如何去了解?我应该使用哪些工具以及我应该在哪里寻找?在.NET中,将空方法调用优化掉了吗?

由于我确定会被问到,空方法的原因是预处理器指令。


@克里斯: 有道理,但它可以优化出来的方法调用。所以该方法仍然存在,但静态调用它可以被删除(或至少内联...)

@Jon: 这只是告诉我,语言编译器不会做任何事情。我认为我需要做的是通过ngen运行我的dll并查看程序集。

回答

1

不,空方法永远不会被优化。这里有几个原因:

  • 的方法可以从 派生类中被调用,也许在 不同的装配
  • 的方法可以 使用反射调用(即使 它被标记为私人)

编辑:是的,从查看那个(exellent)代码项目文档JITer将消除对空方法的调用。但是由于我列出的原因,这些方法本身仍然会被编译并成为你的二进制文件的一部分。

1

所有事情都是平等的,是的,它应该被优化。 JIT在适当的地方内联函数,并且有几件事情比空函数更合适:)

如果您确实想确定,那么更改空方法以抛出异常并打印出它包含的堆栈跟踪。

12

这章有相当好的治疗JIT的优化的,做网页上搜索“的方法是空的”,这是大约一半一路下滑的文章 -

http://www.codeproject.com/KB/dotnet/JITOptimizations.aspx

显然是空虚的方法都得到通过内联进行优化,实际上没有代码。

@Chris:我意识到这些方法仍然是二进制文件的一部分,并且这些都是JIT优化:-)。在一个半相关的说明,斯科特汉塞尔尔曼曾在发布版本中调用堆栈上的内联很有趣的文章:

http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx

0

@乔恩Limjap:我们已经知道C#编译器不会优化空方法了。由于你用ildasm反编译的东西是由C#编译器生成的......在那里没有帮助。

10

我猜你的代码是这样的:

void DoSomethingIfCompFlag() { 
#if COMPILER_FLAG 
    //your code 
#endif 
} 

这不会得到优化掉了,但是:

partial void DoSomethingIfCompFlag(); 

#if COMPILER_FLAG 
partial void DoSomethingIfCompFlag() { 
    //your code 
} 
#endif 

第一个空的方法是局部的,和C#编译器3将优化它。


顺便说一下:这基本上是部分方法的用途。微软向他们的Linq设计人员添加了代码生成器,这些设计人员需要调用默认不做任何事情的方法。

而不是强迫您重载该方法,您可以使用部分。

通过这种方式,partials可以完全优化,如果不使用并且性能不会丢失,而不是增加额外空方法调用的开销。

+1

使用属性[Conditional(“COMPILER_FLAG”)]将具有相同的效果,并且可能更容易使用。请参阅http://msdn.microsoft.com/en-us/library/4xssyw96.aspx – Eric 2014-04-26 07:08:27