首页 > 解决方案 > 是否应该为重复访问的特定索引处的数组元素引入局部变量?

问题描述

如果在循环中重复访问特定索引处的数组元素,是否应该在性能上引入局部变量?阿卡。按索引访问数组会带来开销吗?


例如

public void test(int[] arr) {
    for (int i = 0; i < (1 << 20); i++) {
        System.out.println(arr[0]);
    }
}
public void test2(int[] arr) {
    int first = arr[0];
    for (int i = 0; i < (1 << 20); i++) {
        System.out.println(first);
    }
}

在性能方面test2()优于test()


更新 - 感兴趣的语言

Golang, C,Java

标签: javaarraysperformancegomemory

解决方案


这个问题完全取决于所使用的语言,更具体地说取决于所使用的工具链(编译器、JIT、解释器等)。由于提供的代码是用 Java 编写的,我将考虑 Java 使用像 HotSpot 这样的主流 JVM 的情况。

只要循环是热循环,主流 JVM 实现就可以轻松地自行优化。实际上,JVM 可以知道这arr[0]是一个常数。这里就是这种情况,特别是如果该函数被执行多次。因此,就像大多数时候一样,这不是问题,除非你得到一个显示它实际上是一个问题的基准,否则你不应该关心这种微优化。建议的优化在这里无关紧要,因为println调用将比循环中的任何其他内容慢几个数量级。

但是请注意,当您有很多小循环并且代码只执行几次或很少执行时,第二个代码可能会稍微快一些。原因是第二个代码会导致效率较低的字节码,由于将字节码编译为快速本机代码的成本(它是为了找到一个折衷方案),JVM 可能无法直接优化该字节码。


推荐阅读