在.NET中,是否会优化空方法调用?

时间:2020-03-05 18:39:47  来源:igfitidea点击:

给定一个空的方法主体,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设计器中添加了代码生成器,这些代码生成器需要调用默认情况下不执行任何操作的方法。

与其强迫我们重载方法,不如使用部分方法。

这样,如果不使用局部函数,则将完全优化,并且不会损失性能,而不是增加额外的空方法调用的开销。