java中`For`循环的最佳实践

时间:2012-05-11 08:20:53

标签: java

  

可能重复:
  for loop optimization

在java中我有一段代码:

List e = {element1, element2, ...., elementn};
for(int i = 0; i < e.size(); i++){//Do something in here
};

和另一个街区:

List e = {element1, element2, ...., elementn};
int listSize = e.size();
for(int i = 0; i < listSize; i++){//Do something in here
};

我认为第二个块更好,因为在第一个块中,如果i++,我们必须再次计算e.size()来比较for循环中的条件。是对还是错? 比较上面的两个块,写作的最佳做​​法是什么?为什么?解释清楚并亲自尝试这个循环

12 个答案:

答案 0 :(得分:14)

就个人而言,我会改用for语句:

for (Object element : e) {
    // Use element
}

当然,除非你需要索引。

如果我使用两种形式中的一种,我会使用第一种,因为它更整洁(它不会引入另一种只在该循环中使用的局部变量),直到我有具体证据表明它引起了问题。 (在大多数列表实现中,e.size()是一个简单的变量访问,无论如何都可以通过JIT内联。)

答案 1 :(得分:6)

通常,最简洁易读的代码是最佳选择,所有条件都相同。对于Java,增强的for循环(适用于任何实现Iterable的类)是可行的方法。

for (Object object : someCollection) { // do something }

仅就你发布的两个而言,我认为第一个是更好的选择。它更具可读性,您必须记住,JIT将尝试优化您编写的大量代码。

编辑:您是否听说过“过早优化是万恶之源”?您的第二个块是过早优化的示例。

答案 2 :(得分:4)

如果检查LinkedList类上的size()实现,则会在列表中添加或删除元素时发现该大小已被强制或减少。 调用size()只返回此属性的值,不涉及任何计算。
因此,直接调用size()方法应该更好,因为你将节省另一个整数。

答案 3 :(得分:3)

我会一直使用(如果你需要一个索引变量):

List e = {element1, element2, ...., elementn};
for(int i = 0, size = e.size(); i < size; i++){
    // Do something in here
};

由于e.size()可能是一项昂贵的操作。

你的第二个选项不好,因为它在for循环之外引入了一个新变量。我建议尽可能限制变量可见性。

否则一个

for (MyClass myObj : list) {
    // Do something here
}

甚至更干净,但可能会带来小的性能损失(索引方法并不需要实例化Iterator)。

答案 4 :(得分:1)

是的,第二种形式的效率略高,因为您不重复执行size()方法调用。编译器本身正在进行这种优化。

但是,这不太可能是您的应用程序的性能瓶颈。 Avoid premature optimisation 即可。使代码最简洁,最易读。

答案 5 :(得分:1)

在大多数情况下,HotSpot会从周期中移动e.size()。所以它只计算一次List的大小。

至于我,我更喜欢以下符号:

for (Object elem: e) {
   //Do something
}

答案 6 :(得分:1)

我认为这应该会好得多.. 可能正在初始化int变量每次都可以从此转义..

List e = {element1, element2, ...., elementn};
int listSize = e.size();
int i=0;
for(i = 0; i < listSize; i++){//Do something in here
};

答案 7 :(得分:0)

我不太确定,但我认为java的优化器将用静态值替换该值,所以最终它将是相同的。

答案 8 :(得分:0)

第二个是更好的方法,因为在第一个块中,您调用e.size()是一个循环中的操作的方法,这对JVM来说是一个额外的负担。

答案 9 :(得分:0)

为了避免所有这些编号和迭代器以及写入代码的检查,请使用以下最简单,性能最高的代码。 为什么这有最大的性能(细节即将出现)

for (Object object : aCollection) { 
// Do something here
}

如果需要索引,则:
在上述两种形式之间进行选择:
第二个是你说的更好,因为它只计算了一次大小。

答案 10 :(得分:0)

我认为现在我们倾向于编写简短易懂的代码,因此第一种选择更好。

答案 11 :(得分:-1)

第二个是更好的,因为在它的身体的第一个循环中,也许你会做这个判断 e.remove,然后e的大小将被更改,因此最好在looop之前将参数中的大小保存