可能重复:
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
循环中的条件。是对还是错?
比较上面的两个块,写作的最佳做法是什么?为什么?解释清楚并亲自尝试这个循环
答案 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之前将参数中的大小保存