.NET运行时在执行代码之前总是进行JIT编译,因此它永远不会被解释。
您可以在CLR Design Choices与Anders Hejlsberg中找到更多有趣的阅读材料。尤其是这部分内容:
我看到微软决定IL始终都会被编译,从不被解释。那么如何在指令中编码类型信息有助于解释器更高效地运行呢?
Anders Hejlsberg: 如果解释器只需要盲目地按照指令执行而无需跟踪堆栈顶部的内容,它就可以更快。例如,当它看到iadd时,解释器不必首先弄清楚这是哪种加法,它知道这是一个整数加法。假设有人已经验证过堆栈的正确性,这样就可以节省一些时间,并且对于解释器来说,这很重要。然而,在我们的情况下,我们从未打算针对CLR进行解释执行的场景。我们打算始终使用JIT [即时编译],为了JIT的目的,我们需要跟踪类型信息。由于我们已经有了类型信息,将其放入指令中并没有带来任何好处。
Bill Venners: 许多现代JVM [Java虚拟机]都进行自适应优化,它们从解释字节码开始。他们在应用程序运行时对其进行分析,找出80%至90%的代码中执行10%至20%,然后将其编译为本地代码。尽管如此,它们不一定会即时编译这些字节码。一个方法的字节码仍然可以在后台被解释器执行时编译为本地代码并进行优化。当本地代码准备就绪时,它可以替换字节码。通过不针对解释执行场景,您是否完全排除了在CLR中采用这种执行方法的可能性?
Anders Hejlsberg: 不,我们并没有完全排除这种可能性。我们仍然可以解释代码,只是我们没有为解释而优化。我们没有针对编写最高性能的解释器进行优化,这种解释器只会解释代码。我认为现在已经没有人会这样做了。10年前,对于一个机顶盒来说,这可能是有趣的。但现在已经不再有趣了。JIT 技术发展到了一个地步,你可以有多种 JIT 策略可选。你甚至可以想象使用一个快速的 JIT 进行快速编译,然后当我们发现正在频繁执行某个特定的方法时,使用另一个 JIT 进行更好的优化并花费更多时间。在 JIT 方面还有很多可以做的。
我不这么认为,也不认为它应该这样做。
JIT如何知道特定方法将被调用多少次?解释的频率不会影响决策吗?
我还要质疑JIT编译器能否很好地分析函数,以确定是否最好进行解释而不解释函数本身。鉴于这个事实(至少已经执行了一遍该方法),是否更好地编译每个方法以减少试图确定首先编译哪些方法的开销?