当您需要索引时,循环数组的最佳方法是什么?
选项1:
int len = array.length;
for (int i = 0; i < len; ++i) {
array[i] = foo(i);
}
选项2:
for (int i = 0; i < array.length; i++) {
array[i] = foo(i);
}
或者,这没关系吗?或者有更好的方法吗? 只是指出差异:在一种情况下,数组的长度作为循环中测试的一部分进行评估,尽管编译器通常应优化它。
<小时/> 其次,++i
与i++
有什么不同?如果是C ++,我肯定更喜欢++i
,但我不确定Java。
答案 0 :(得分:6)
i++
vs ++i
无关紧要。虽然C大师会告诉你将array.length存储在一个变量中,但现代优化编译器在这种情况下只要长度不会在循环中发生变化就不必要了。如果你真的担心你可以对两者进行基准测试,但是因为.length
实际上并不需要每次你都可以遍历整个数组。
答案 1 :(得分:6)
通常这两种方法是等价的。你应该注意到
for (int i = 0 ; i < foo() ; i++) {
...
}
foo()
在每次迭代之前调用一次(而不是在第一次迭代之前只调用一次),因此您可能希望通过执行类似
int n = foo();
for (int i = 0 ; i < n ; i++) {
...
}
类似于选项1 。所以我会说选项1 肯定是两者中更安全的,但大多数时候它不会产生显着差异你使用。
至于你的第二个问题:++i
首先递增你的变量,然后检索它的值,i++
首先检索该值,然后递增。试试这两段代码:
int i = 0;
System.out.println(++i);
------------------------
int i = 0;
System.out.println(i++);
第一次打印1
,但第二次打印0
。当然,当++i
和i++
单独存在时,它没有任何区别。
答案 2 :(得分:0)
是否在for循环中使用“array.length”: 通常编译器会进行一些优化,因此它等同于在for循环中使用变量
表示“i ++”和“++ i” 在C ++中,++ i是首选且更有效,但在Java中,它们在这种情况下是等效的。
答案 3 :(得分:0)
除了arshaji响应之外,我想知道在循环中使用size()
与预先存储它是否有性能优势。我相信结果表明编译器确实优化了事物并且访问列表的长度与访问变量相同(我担心它必须通过函数的事实会减慢事情)。
以下是这两种循环方法所需的时间:
for(long i = 0 ; i < mylist.size(); i++){}
VS
for(long i = 0 ; i < 10_000_000; i++){}
以下是一千万个元素列表的结果:
fixed length:
,162,157,151,157,156,159,157,149,150,170,158,153,152,158,151,151,156,156,151,153
getSize:
,164,156,159,154,151,160,162,152,154,152,151,149,168,156,152,150,157,150,156,157
import java.util.ArrayList;
import java.util.List;
public class Main {
final static int LENGTH_SAMPLE = 20;
final static long LENGTH = 10_000_000;
public static void main(String[] args) {
List<Long> mylist = new ArrayList<>();
for(long i = 0 ; i < LENGTH; i++){
mylist.add(i);
}
System.out.println("fixed length:");
for(int i = 0 ; i < LENGTH_SAMPLE; i++){
System.out.printf("," + fixedSize(mylist));
}
System.out.println("");
System.out.println("getSize:");
for(int i = 0 ; i < LENGTH_SAMPLE; i++){
System.out.printf("," + fctSize(mylist));
}
}
private static long fixedSize(List list){
long start = System.currentTimeMillis();
for(long i = 0 ; i < LENGTH; i++){
System.currentTimeMillis();
}
return System.currentTimeMillis() - start;
}
private static long fctSize(List list){
long start = System.currentTimeMillis();
for(long i = 0 ; i < list.size(); i++){
System.currentTimeMillis();
}
return System.currentTimeMillis() - start;
}
}