for (int i=0; i<arr.length; i++) {
}
这将产生一个代码:
getstatic #4;
arraylength
而下面的代码:
int length = arr.length;
for (int i=0; i<length; i++) {
}
将被编译为:
iload_3
这两个片段之间有区别吗?哪个代码运行得更快?
如您所见,在我的例子中,数组是一个静态成员。确切地说是静态的和最终的。考虑到 JIT 优化,基本的优化器可以感知并将数组的长度硬编码到方法的机器代码中。使用局部变量(第二种情况)更难遵循此逻辑,因此人们会认为第一个比第二个更有可能被优化。
最佳答案
因为它是静态的和最终的,我怀疑它可以对长度进行硬编码,尽管我不确定它会走那么远。但是 JIT 编译器在处理第一种形式时可能仍然比第二种形式做得更好。
特别是,如果它可以检测到数组在循环内没有改变,它可以避免多次评估长度并在循环内删除数组边界检查 - 它可以验证您永远不会访问 [0, length)
范围之外的数组。
我希望到现在为止,体面的 JIT 也会注意到第二种形式 - 但为了可读性,我仍然更喜欢第一种形式,并且我想要证据 在更改为第二个之前,它的性能不如第二个。
一如既往,首先编写最具可读性的代码,但根据性能要求对其进行衡量。
关于Java 性能 : arraylength vs iload,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6071949/