给定一个空的方法体,JIT 是否会优化调用(我知道 C# 编译器不会)。我将如何去发现?我应该使用什么工具,我应该在哪里寻找?
因为我确定它会被问到,所以空方法的原因是预处理器指令。
@Chris:有道理,但它可以优化对方法的调用。所以该方法仍然存在,但可以删除对它的静态调用(或至少内联......)
@Jon:这只是告诉我语言编译器没有做任何事情。我认为我需要做的是通过 ngen 运行我的 dll 并查看程序集。
给定一个空的方法体,JIT 是否会优化调用(我知道 C# 编译器不会)。我将如何去发现?我应该使用什么工具,我应该在哪里寻找?
因为我确定它会被问到,所以空方法的原因是预处理器指令。
@Chris:有道理,但它可以优化对方法的调用。所以该方法仍然存在,但可以删除对它的静态调用(或至少内联......)
@Jon:这只是告诉我语言编译器没有做任何事情。我认为我需要做的是通过 ngen 运行我的 dll 并查看程序集。
这个章节对 JIT 优化有很好的处理,在页面上搜索“方法为空”,它大约在文章的一半 -
http://www.codeproject.com/KB/dotnet/JITOptimizations.aspx
显然,空方法确实通过内联实际上没有代码的内容得到优化。
@Chris:我确实意识到这些方法仍然是二进制文件的一部分,并且这些是 JIT 优化:-)。在一个半相关的注释中,Scott Hanselman 有一篇关于在 Release 构建调用堆栈中内联的非常有趣的文章:
我猜你的代码是这样的:
void DoSomethingIfCompFlag() {
#if COMPILER_FLAG
//your code
#endif
}
但是,这不会得到优化:
partial void DoSomethingIfCompFlag();
#if COMPILER_FLAG
partial void DoSomethingIfCompFlag() {
//your code
}
#endif
第一个空方法是部分的,C#3 编译器会对其进行优化。
顺便说一句:这基本上就是部分方法的用途。微软向他们的 Linq 设计器添加了代码生成器,这些代码生成器需要调用默认情况下不执行任何操作的方法。
与其强迫您重载方法,不如使用部分方法。
这样,如果不使用,部分将被完全优化,并且不会损失性能,而不是增加额外的空方法调用的开销。
不,空方法永远不会被优化。以下是几个原因:
编辑:是的,通过查看那个(出色的)代码项目文档,JITer 将消除对空方法的调用。但是由于我列出的原因,这些方法本身仍将被编译并成为您的二进制文件的一部分。
一切都是平等的,是的,它应该被优化出来。JIT 在适当的地方内联函数,没有什么比空函数更合适了:)
如果您真的想确定,请更改您的空方法以引发异常并打印出它包含的堆栈跟踪。