eol*_*old 12 java performance static-methods inline
我感兴趣的是我是否应该手动内联在一些性能敏感算法中称为100k-100万次的小方法.
首先,我认为,由于没有内联,我会产生一些开销,因为JVM必须找到是否要内联这个方法(甚至不能这样做).
然而,前几天,我用静态方法的调用替换了这个手动内联代码,并看到了性能提升.怎么可能?这是否表明实际上没有开销,让JVM内联"意志"实际上提升了性能?或者这在很大程度上取决于平台/架构?
(发生性能提升的例子是用int t = a[i]; a[i] = a[j]; a[j] = t;静态方法调用替换数组交换()swap(int[] a, int i, int j).另一个没有性能差异的例子是当我内联一个10-liner方法时,称为1000000次.)
irr*_*ble 12
我见过类似的东西."手动内联"不一定更快,结果程序可能太复杂而无法进行优化分析.
在你的例子中,让我们做一些疯狂的猜测.当您使用swap()方法时,JVM可能能够分析方法体,并得出结论,由于i和j不会更改,尽管有4个数组访问,但只需要2个范围检查而不是4个.局部变量t不是必需的,JVM可以使用2个寄存器来完成工作,而不涉及t堆栈的r/w .
之后,swap()的主体被内联到调用方法中.这是在上一次优化之后,因此保存仍然存在.调用者方法体甚至可能证明i和j总是在范围内,因此剩下的2个范围检查也被删除.
现在在手动内联版本中,优化器必须立即分析整个程序,变量太多,动作太多,可能无法证明保存范围检查或消除局部变量是安全的t.在最坏的情况下,这个版本可能需要花费6个以上的内存访问来进行交换,这是一个巨大的开销.即使只有1个额外的内存读取,它仍然非常明显.
当然,我们没有理由认为手动"概述"总是更好,即提取小方法,如愿以为它会帮助优化器.
-
我所学到的是,忘记手动微优化.并不是我不关心微观性能改进,而是我始终信任JVM的优化.这是我完全不知道该做什么比做坏事更好.所以我放弃了.
JVM可以非常有效地内联小方法.如果您可以删除代码,即通过内联来简化它的功能,那么唯一能够自我介绍的好处是.
JVM在识别这些结构时会查找某些结构并进行一些"手动编码"优化.通过使用交换方法,JVM可以识别结构并通过特定优化以不同方式对其进行优化.
您可能有兴趣尝试OpenJDK 7调试版本,该版本可以选择打印出它生成的本机代码.