我在java中查看了一个项目,发现了一个for循环,如下所示:
for(int i=1; i<a.length; i++)
{
...........
...........
...........
}我的问题是:计算a.length (这里是一个is数组名)是否很昂贵?如果不是,那么a.length是如何在内部计算的(意味着JVM如何确保O(1)对此的访问)?Is类似于:
int length = a.length;
for(int i=1; i<length; i++)
{
...........
...........
...........
}也就是说,就像访问函数中局部变量的值一样。谢谢。
发布于 2013-08-01 15:34:08
我的问题是:计算a.length费用昂贵吗?
不是的。它只是数组上的一个字段(参见JLS第10.7节)。它并不昂贵,JVM知道它永远不会改变,并且可以适当地优化循环。(实际上,我希望一个好的JIT注意到用非负数初始化变量的正常模式,检查它是否小于length,然后访问数组--如果它注意到了,它可以删除数组边界检查。)
发布于 2013-08-01 15:34:15
a.length不是计算,而是对数组中字段的访问。那种类型的读取操作非常快。
如果代码是经常调用的方法的一部分,那么几乎可以肯定的是,JIT编译器将进行您建议的优化,以使其更快。
潜在的速度差是以纳秒为单位的(可能没有"s")。
发布于 2013-08-01 16:05:27
为了方便你,我给它做了微基准。守则:
public class ArrayLength
{
static final boolean[] ary = new boolean[10_000_000];
static final Random rnd = new Random();
@GenerateMicroBenchmark public void everyTime() {
int sum = rnd.nextInt();
for (int i = 0; i < ary.length; i++) sum += sum;
}
@GenerateMicroBenchmark public void justOnce() {
int sum = rnd.nextInt();
final int length = ary.length;
for (int i = 0; i < length; i++) sum += sum;
}
}结果:
Benchmark Mode Thr Cnt Sec Mean Mean error Units
o.s.ArrayLength.everyTime thrpt 1 3 5 40215.790 1490.800 ops/msec
o.s.ArrayLength.justOnce thrpt 1 3 5 40231.192 966.007 ops/msec摘要:无可检测的变化。
https://stackoverflow.com/questions/17998386
复制相似问题