Str*_*kop 51 java arrays premature-optimization
在为我们的应用程序中的每个循环更新for循环时,我遇到了很多这些"模式":
for (int i = 0, n = a.length; i < n; i++) {
...
}
Run Code Online (Sandbox Code Playgroud)
代替
for (int i = 0; i < a.length; i++) {
...
}
Run Code Online (Sandbox Code Playgroud)
我可以看到你获得了集合的性能,因为你不需要为每个循环调用size()方法.但是有阵列?
所以问题出现了:array.length比常规变量更贵?
jjn*_*guy 69
不,呼叫array.length是O(1)或恒定时间操作.
由于.lengthis(行为)是其public final成员array,因此访问本地变量并不慢.(这与调用方法非常不同size())
现代JIT编译器可能.length无论如何都会优化调用.
您可以通过查看OpenJDK中JIT编译器的源代码,或通过让JVM转储出JIT编译的本机代码并检查代码来确认这一点.
请注意,可能存在JIT编译器无法执行此操作的情况; 例如
Gra*_*ner 17
午饭时我有点时间:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
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
Run Code Online (Sandbox Code Playgroud)
笔记:
n = a.length显示比i < a.length大约一半快,可能是由于垃圾收集(?).250000000因为我得到了OutOfMemoryError,所以我不能做得更大270000000.重点是,并且它是其他人一直在制作的,你必须运行Java内存,你仍然没有看到两个替代品之间的速度有显着差异.把你的开发时间花在真正重要的事情上.
IRB*_*BMe 11
我怀疑是否有任何重大差异,即使有,我敢打赌它可能在编译期间被优化掉了.当你尝试微观优化这样的事情时,你会浪费你的时间.首先使代码可读和正确,然后如果遇到性能问题,请使用分析器,然后担心选择更好的数据结构/算法,然后担心优化探查器突出显示的部分.
数组的长度存储为Java中数组的成员变量(与元素不同),因此获取该长度是一个常量时间操作,与从常规类中读取成员变量相同.许多较旧的语言(如C和C++)不会将长度存储为数组的一部分,因此您需要在循环开始之前存储长度.你不必在Java中这样做.