我们知道每个数组元素访问上的Java都会检查索引是否超出范围。但是在某些情况下,比如Scala中的map函数,编译器/库会自己处理索引,从而保证不会出现越界访问。可以在Java/Scala中禁用边界检查吗?
因此,出于性能方面的原因,可以在JVM中禁用某些代码部分的边界检查吗?
我们知道每个数组元素访问上的Java都会检查索引是否超出范围。但是在某些情况下,比如Scala中的map函数,编译器/库会自己处理索引,从而保证不会出现越界访问。可以在Java/Scala中禁用边界检查吗?
因此,出于性能方面的原因,可以在JVM中禁用某些代码部分的边界检查吗?
不,数组范围检查不能被禁用。这会让JVM变得不安全。
但是,JIT编译器可能能够推断出某些范围检查是不必要的,并将它们优化掉。
另外,JIT编译器可能对某些内建类型“聪明”。您可以通过在本机代码中实现东西来侧身解决问题,但您可能会发现,进行本地调用的开销大大减少了本地执行计算的成本。
你能可能显示一些示例代码,其中JIT会推断出没有界限,需要检查?
不是没有比我愿意:-)
然而,一些花费更多的时间,JIT编译器在理论上可以推断,没有数组的边界在这里需要检查:
public int sum(int[] array) {
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum += array[i];
}
return sum;
}
而在这种情况下,简单的窥孔优化应该消除循环体中的第二边界检查:
public int sum2(int[] array) {
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum += array[i];
sum += array[i];
}
return sum;
}
你可能会展示一些示例代码,其中JIT会推断没有边界检查是必需的? – pythonic
边界检查很少是实际的性能瓶颈,因为它经过了大量优化(至少循环挂起)。如果你已经完成了指令级分析以确认实际情况,那么你可以考虑使用'Unsafe'来绕过检查。但据我所知,没有一个JDK类可以做这样的事情,只有少数第三方的高性能库可能会这样。 – the8472