如果启用优化,JIT 是不是总是内联此方法?

Posted

技术标签:

【中文标题】如果启用优化,JIT 是不是总是内联此方法?【英文标题】:If optimizations are enabled will the JIT always inline this method?如果启用优化,JIT 是否总是内联此方法? 【发布时间】:2010-11-23 12:03:25 【问题描述】:

我并不期待一个明确的是或否。您可能拥有的任何知识我都会考虑作为答案。

private String CalculateCharge(Nullable<Decimal> bill, Nullable<Decimal> rate)

    return ((bill ?? 0.0m) * (rate ?? 0.0m)).ToString("C");

【问题讨论】:

很难说“是”,但由于它是私人的,我会这么认为。 C# 编译器从不内联任何东西。有关 C# 编译器(而不是 jit 编译器)执行的优化列表,请参阅我关于该主题的文章。 blogs.msdn.com/ericlippert/archive/2009/06/11/… 谢谢 Eric,看来我还有很多工作要做。 【参考方案1】:

内联是 JIT 的实现细节,而不是 C# 编译器的实现细节。来自Eric Gunnerson's blog:

JIT 使用许多启发式方法 决定一个方法是否应该 内联。 以下是名单 其中更重要的(注意 这并不详尽):

大于 32 字节 IL 的方法将不会被内联。 虚拟函数没有内联。 具有复杂流控制的方法不会被内联。复杂的 流量控制是任何其他流量控制 比如果/那么/否则;在这种情况下, 切换或同时。 不包含异常处理块的方法 内联,尽管方法会抛出 例外仍然是候选人 内联。 如果方法的任何形式参数是结构,则该方法将 不被内联。

虽然你的方法很短而且不是很复杂,所以它可能与启发式匹配,Nullable&lt;T&gt;struct,所以我猜你的方法没有内联。

根据经验,如果内联此方法提高了性能,JIT 将内联此方法;否则不会。但这实际上是 JIT 的实现细节,您无需编写任何代码:

我会仔细考虑对这些启发式进行显式编码,因为它们可能会在 JIT 的未来版本中发生变化。不要为了保证它会被内联而损害方法的正确性。

编辑: 显然,关于结构没有被内联的部分已经过时了;更新信息可以在Vance Morrison's blog找到。

【讨论】:

从 .NET 3.5sp1 开始,struct 选项不再适用。现在可以内联结构参数。 @Reed Copsey:感谢您提供的信息。事实证明:)

以上是关于如果启用优化,JIT 是不是总是内联此方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测是不是启用了 PHP JIT

Java JIT 是不是曾经优化递归方法调用?

JIT即时编译器(C1和C2)

浅谈Java JIT编译器概念

浅谈Java JIT编译器概念

php8编译安装开启opcache和jit配置