我想知道为什么JVM的JIT编译器会忽略"巨大的方法"来自编译。 (除非DontCompileHugeMethods
标志设置为false。)同时,大多数关于Java的JIT编译器的说法都表明内联是 uber-optimization 因为它允许增长大量的指令需要编译。这个更大的编译上下文允许更好地优化执行的代码。有了这个,我认为一个巨大的方法与一个内联方法很大不一样,应该是JIT编译的一个很好的目标。我在这里缺少什么?
答案 0 :(得分:3)
基本上,编制大量方法的投资回报率很低。
热门代码通常很短。
即使经常执行一个庞大的方法,热门部分也不太可能涵盖整个方法。
例如。考虑一个大的switch
语句,其中只经常执行少量case
个标签。
但是编译单元是一种方法 - 所以JITted代码的大部分内容都是浪费。
大型方法的编译需要大量的时间和空间。而且,编译时间不会线性增长。 编译几个小方法会更有利可图。
太长的机器代码会污染指令缓存。
某些优化更适用于较小的代码段,例如:注册分配或循环展开。
如果单个方法的大小超过8K字节码,那么它的编写效果似乎很差。
答案 1 :(得分:1)
8k的限制可能只是一个过时的启发式。回到日期[TM],JITing有点昂贵(特别是从响应性的观点来看)。事实上,最有趣的优化(认为常数折叠,良好的寄存器分配等)是超线性的。因此,您需要格外小心,不要停止整个过程半秒钟来运行优化任务,这可能只会产生一小部分时间作为性能提升。
然而,我认为随着经验的增长,更快的处理器和更好的JIT技术,限制可能会有所提升(可能甚至达到一个数量级),但超线性性能的核心问题仍然存在,因此,限制。