在.NET中,是否会优化空方法调用?
给定一个空的方法主体,JIT将优化调用(我知道Ccompiler不会)。我将如何寻找答案?我应该使用什么工具,应该在哪里看?
由于我敢肯定会问这个问题,所以空方法的原因是预处理程序指令。
@克里斯:
是有道理的,但是它可以优化对方法的调用。因此该方法仍然存在,但是可以删除对其的静态调用(或者至少是内联的...)
@乔恩:
这只是告诉我语言编译器没有执行任何操作。我认为我需要做的是通过ngen运行我的dll并查看程序集。
解决方案
回答
不,空方法永远不会被优化。以下是几个原因:
- 可以从派生类中调用该方法,也许在不同的程序集中
- 可以使用Reflection调用该方法(即使已将其标记为私有)
编辑:是的,通过查看该(出色的)代码项目doc,JITer将消除对空方法的调用。但是由于我列出的原因,这些方法本身仍将被编译为二进制文件的一部分。
回答
万物都是平等的,是的,应该对其进行优化。 JIT在适当的地方内联函数,并且没有什么比空函数更合适的了:)
如果我们确实希望确定,请更改空方法以引发异常并打印出其包含的堆栈跟踪。
回答
本章很好地处理了JIT优化问题,在页面上搜索"方法为空",大约在文章的一半处-
http://www.codeproject.com/KB/dotnet/JITOptimizations.aspx
显然,空方法确实可以通过内联什么没有代码的方法得到优化。
@Chris:我确实意识到这些方法仍将是二进制文件的一部分,并且这些都是JIT优化:-)。关于一个半相关的注释,Scott Hanselman有一篇非常有趣的文章,涉及内联在Release build调用堆栈中:
http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx
回答
@Jon Limjap:我们已经知道Ccompiler不会优化空方法。由于我们使用ildasm反编译的内容是Ccompiler生成的,因此没有任何帮助。
回答
我猜你的代码是这样的:
void DoSomethingIfCompFlag() { #if COMPILER_FLAG //your code #endif }
但是,这不会被优化:
partial void DoSomethingIfCompFlag(); #if COMPILER_FLAG partial void DoSomethingIfCompFlag() { //your code } #endif
第一个空方法是部分方法,C#3编译器将对其进行优化。
顺便说一句:这基本上是部分方法的用途。微软在其Linq设计器中添加了代码生成器,这些代码生成器需要调用默认情况下不执行任何操作的方法。
与其强迫我们重载方法,不如使用部分方法。
这样,如果不使用局部函数,则将完全优化,并且不会损失性能,而不是增加额外的空方法调用的开销。