java for循环比较大小_java – 在for循环比较中使用集合大小

Java中的Collections的size()方法是否有编译器优化?

请考虑以下代码:

for(int i=0;i

...some operation.....

每个i都调用size()方法.找出尺寸并重复使用它不是更好吗? (方法调用有开销).

final int len = list.size()

for(int i=0;i

...some operation.....

但是,当我为这两个代码片段计时时,没有显着的时间差异,即使我高达10000000.

我在这里错过了什么吗?

Update1:​​我知道除非集合发生变化,否则不再计算大小.但是必须有一些与方法调用相关的开销.编译器是否总是内联这些(参见Esko的答案)?

更新2:我的好奇心得到了进一步的推动.从给出的答案中,我看到好的JIT编译器经常会内联这个函数调用.但他们仍然需要确定该集合是否被修改.我不接受答案,希望有人能给我指点如何由编译器处理.

解决方法:

好的,这里是JDK源代码的摘录(JDK文件夹中的src.zip):

public int size() {

return size;

}

这是来自ArrayList,但我认为其他集合具有类似的实现.现在,如果我们想象编译器内联size()调用(这将是完全合理的),你的循环变为:

for(int i=0;i

// ...

(好吧,让我们忘记大小是私有的.)编译器如何检查集合是否被修改?答案是它没有也不需要这样做,因为该字段已经在字段中可用,所以它所要做的就是在每次迭代时访问size字段,但访问int变量非常快操作.请注意,它可能只计算一次地址,因此它甚至不必在每次迭代时取消引用列表.

例如,通过add()方法修改集合会发生什么?

public boolean add(E e) {

ensureCapacity(size + 1); // Increments modCount!!

elementData[size++] = e;

return true;

}

如您所见,它只会增加大小字段.因此编译器实际上不需要做任何事情来确保它可以访问最新的大小.唯一的例外是,如果从另一个线程修改集合,则需要进行同步,否则循环线程可能会看到其本地缓存的大小值,可能会也可能不会更新.

标签:java,collections

来源: https://codeday.me/bug/20190925/1816146.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值