为了账号安全,请及时绑定邮箱和手机立即绑定

调用array.length的成本是多少

/ 猿问

调用array.length的成本是多少

慕标琳琳 2019-08-19 17:16:56

调用array.length的成本是多少

在为我们的应用程序中的每个循环更新for循环时,我遇到了很多这些“模式”:

for (int i = 0, n = a.length; i < n; i++) {
    ...}

代替

for (int i = 0; i < a.length; i++) {
    ...}

我可以看到你获得了集合的性能,因为你不需要为每个循环调用size()方法。但是有阵列?

所以问题出现了:array.length比常规变量更贵?


查看完整描述

3 回答

?
慕田峪9158850

不,呼叫array.lengthO(1)或恒定时间操作。

由于.lengthis(行为)是其public final成员array,因此访问本地变量并不慢。(这与调用方法非常不同size()

现代JIT编译器可能.length无论如何都会优化调用。

您可以通过查看OpenJDK中JIT编译器的源代码,或通过让JVM转储出JIT编译的本机代码并检查代码来确认这一点。

请注意,可能存在JIT编译器无法执行此操作的情况; 例如

  1. 如果您正在调试封闭方法,或者

  2. 如果循环体有足够的局部变量来强制寄存器溢出。


查看完整回答
反对 回复 2019-08-19
?
慕的地6264312

午饭时我有点时间:


public static void main(String[] args) {

    final int[] a = new int[250000000];

    long t;


    for (int j = 0; j < 10; j++) {

        t = System.currentTimeMillis();

        for (int i = 0, n = a.length; i < n; i++) { int x = a[i]; }

        System.out.println("n = a.length: " + (System.currentTimeMillis() - t));


        t = System.currentTimeMillis();

        for (int i = 0; i < a.length; i++) { int x = a[i]; }

        System.out.println("i < a.length: " + (System.currentTimeMillis() - t));

    }

}

结果:


n = a.length: 672

i < a.length: 516

n = a.length: 640

i < a.length: 516

n = a.length: 656

i < a.length: 516

n = a.length: 656

i < a.length: 516

n = a.length: 640

i < a.length: 532

n = a.length: 640

i < a.length: 531

n = a.length: 641

i < a.length: 516

n = a.length: 656

i < a.length: 531

n = a.length: 656

i < a.length: 516

n = a.length: 656

i < a.length: 516

笔记:


如果你反转测试,那么n = a.length显示比i < a.length大约一半快,可能是由于垃圾收集(?)。

250000000因为我得到了OutOfMemoryError,所以我不能做得更大270000000。

重点是,并且它是其他人一直在制作的,你必须运行Java内存,你仍然没有看到两个替代品之间的速度有显着差异。把你的开发时间花在真正重要的事情上。


查看完整回答
反对 回复 2019-08-19
?
胡说叔叔

我怀疑是否有任何重大差异,即使有,我敢打赌它可能在编译期间被优化掉了。当你尝试微观优化这样的事情时,你会浪费你的时间。首先使代码可读和正确,然后如果遇到性能问题,请使用分析器,然后担心选择更好的数据结构/算法,然后担心优化探查器突出显示的部分。


查看完整回答
反对 回复 2019-08-19

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信