java - java 是否在 for 循环中缓存数组引用?

标签 java performance for-loop foreach

还有类似的问题:

高级 for 循环会缓存引用,因为它使用相同的迭代器实例: https://stackoverflow.com/a/29812538/4087512

正常的 for 循环会缓存长度:https://stackoverflow.com/a/1208331/4087512

但是我想看看引用是否缓存在经典的for循环中:

for(int i=0; i<someObject.getPrivateArray().length; i++){
    //do something where it's necessary to use i AND getPrivateArray()
}

相对于:

int j=0;
for(int var : someObject.getPrivateArray()){
    //do something with j & var
    j++;
}

从这里回答的问题:Is there a performance difference between a for loop and a for-each loop?这两个在本地作用域中声明的数组上具有相同的性能,但是在 for 循环中从不同的对象获取数组会产生开销吗?上面已经回答了,数组实际上是在foreach循环中缓存的。

最佳答案

没有。

Java 无法知道 someObject.getPrivateArray() 在每次调用时都会返回相同的对象。因此,它必须在每次迭代时调用该函数。

例如)

Queue<int[]> queue = ...;

for(int i=0; i<queue.remove().length; i++) {
    // ...
}

这是完全相同的代码模式;只是名称发生了变化,但很明显 queue.remove() 的返回值不会被缓存。


更新

@MattTimmermans 在评论中指出,JVM 可能会内嵌 someObject.getPrivateArray() 调用,以便 JVM 能够确定每次返回相同的对象,并优化掉电。这需要:

  • someObject 是最终的或实际上是最终的
  • getPrivateArray() 是最终的,因此可以内联
  • getPrivateArray() 必须无副作用(或者无论如何都必须执行副作用)
  • 返回值必须是final,这样其他实体就无法修改它,从而保证返回相同的值

在这种情况下,JVM可能会优化调用并将提取移出循环,从而有效地缓存结果。我不会依赖它,因为自己缓存值很容易做到。

关于java - java 是否在 for 循环中缓存数组引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57085828/

相关文章:

c# - IEnumerable 在使用后是否存储对象

c - #include .c 源文件是否可以用于嵌入式 C 代码的可维护性?

javascript - 是否可以在设置超时的情况下延迟 for 循环中的变量?

java - 新的(但不同的)Facebook ApplicationId 导致 NPE

java - Cmd 错误 - 存储空间不足,无法处理此命令

java - GWT 应用程序 404 以托管模式连接到 RPC servlet

c# - 为什么JIT订单会影响性能?

重新整理数据框

c# - 我该怎么做才能使这个循环运行得更快?

java - 了解 Java 中泛型的语法