题
我已经观察到了应用程序中的许多“堆栈introspective”代码 不是 因其正确性而被绑架。这样的方法通常涉及到:
MethodBase.GetCurrentMethod
Assembly.GetCallingAssembly
Assembly.GetExecutingAssembly
现在,我发现围绕这些方法的信息非常令人困惑。我听说运行时不会嵌入一个调用GetCurrentMethod的方法,但我找不到任何文档来实现这种效果。我几次看过Stackoverflow上的帖子,例如 这个, ,指示CLR不会在线交叉组装呼叫,而是 GetCallingAssembly
文档 强烈指示其他方式。
也有很多疑问 [MethodImpl(MethodImplOptions.NoInlining)]
, ,但我不确定CLR是否认为这是“请求”或“命令”。
请注意,我在询问有关内部的信息 合格 从合同的角度来看 不是 关于当前抖动的实施何时由于实施困难而拒绝考虑方法,或者何时何时最终结束 选择 在评估权衡后,在符合条件的方法中内联方法。我读过了 这个 和 这个, ,但它们似乎更专注于最后两个方面(正在提及方法论面。 义务).
什么时候CLR 允许 内联?
解决方案
这是一个抖动的实现细节,x86和x64抖动具有不同的规则。这是在抖动工作的团队成员的博客文章中随意记录的,但团队肯定保留更改规则的权利。看起来您已经找到了它们。
肯定会支持其他集会的方法,如果事实并非如此。当您查看为console.writeline()生成的机器代码时,您可以在工作中看到它,当您传递简单的字符串时,它通常会被内衬。要亲自查看此内容,您需要切换到发布构建并更改调试器选项。工具 +选项,调试,一般,打开“抑制对模块负载的JIT优化”。
否则没有充分的理由考虑methodimpotions。非误解,这几乎是为什么它首先存在的原因。实际上,它在.NET框架中有意使用许多称为内部辅助方法的小型公共方法。它使异常堆栈跟踪易于诊断。
其他提示
汉斯传递的回答尽管如此 这里 首先,截至2004年,有几个提示,并进一步了解更多最新信息。它们可能会发生变化,但是如果您想制作有资格的内部方法:
JIT不会嵌入式:
- 用方法imploptions.noinlining标记的方法
- 大于32个字节IL的方法
- 虚拟方法
- 将大价值类型作为参数的方法
- 元帅课程的方法
- 带有复杂流程图的方法
- 符合其他更异国标准的方法
特别是 methodimploptions, ,这应该取消32个字节的限制(或如今的平台和平台上的任何东西)。
.NET 3.5添加了启发式方法,可以帮助它确定是否是否 内联或不在线, ,这可能是一件好事,尽管这使开发人员更难预测抖动的决定:
文章的报价:
如果内部的代码较小,则呼叫替换,它总是很好。请注意,我们谈论的是本地代码大小,而不是IL代码大小(可能完全不同)。
执行特定的呼叫站点越多,它就会从INLNING中受益。因此,循环中的代码值得被列入的代码不仅仅是不在循环中的代码。
如果内在揭示了重要的优化,那么内部的内部是更可取的。在具有价值类型参数的特定方法中,由于这样的优化,因此具有比正常情况更大的好处,因此存在偏见来嵌入这些方法是好的。
因此,X86 JIT编译器使用的启发式是给出的候选者。
如果该方法未内衬,则估计呼叫站点的大小。
估计呼叫站点的大小,如果它是内衬的(这是基于IL的估计值,我们使用一个简单的状态机(Markov模型),使用大量实际数据创建来形成此估算器逻辑)
计算乘数。默认情况下是1
如果代码处于循环中,则增加乘数(当前的启发式将其撞到5中)
如果乘数看起来会启动,则增加乘数。
如果Inlineize <= nonlinizizize *乘数进行内部。
有更多有关Methodbase.getCurrentMethod的信息 http://prdlxvm0001.codify.net/pipermail/ozdotnet/2011-march/009085.html
它严重地指出,Refcrawlmark并没有停止呼叫方法被内衬。但是,需要估算确实具有阻止呼叫者被绑定的侧面影响。
此外,汇编。getCallingAssembly和汇编。GetExeCutingAssembly方法没有此属性。
2003年在MSDN上发布了一篇文章 编写高性能托管应用程序 这涵盖了概述的几个标准:
- 不超过32个字节的IL的方法不会被归类。
- 虚拟函数没有嵌入。
- 具有复杂流控制的方法不会被衬里。复杂的流量控制是除/then/否时的任何流控制;在这种情况下,切换或稍加切换。
- 包含异常处理块的方法并未嵌入,尽管抛出异常的方法仍然是候选人的内衬。
- 如果该方法的任何形式论点是构造,则该方法不会被归类。
Sacha Goldshtein在2012年的博客文章 在CLR中的积极内线 有很多相同的建议。