循环效率优化

3

我正在编写一款Android游戏,尽可能地提高效率。

我知道for循环比foreach更高效,但我想知道以下两个项目的效率是否有差异:

// itemsList is an ArrayList

int length = itemsList.size();            

for(int i=0; i < length; i++)
{
   // do stuff
}

VS

for(int i=0; i < itemsList.size(); i++)
{
   // do stuff
}

12
你测量过它,你学到了什么? - S.Lott
2
如果列表是ArrayList,使用foreach循环可能会稍微慢一些,但如果列表是LinkedList,则使用foreach循环可能会更快,因为对链表的索引访问速度较慢。无论列表的具体类型如何,foreach循环(或显式使用迭代器)都是最好的循环结构。 - JB Nizet
6个回答

11

视情况而定。理论上第一个会更快,因为第二个需要在每次迭代中进行函数调用。但实际上,这可能得到很大程度的优化。大小可能会缓存在对象中,这只留下了函数调用的开销(几乎可以忽略不计)。

但是如果有疑问,选择第一个。它不会更慢。

但总体来说,要记住:过早优化是万恶之源。

不要因为认为某个解决方案可能快上一纳秒而选择它。相反,请编写好的、坚实的、最重要的是易读的代码。然后,优化真正的瓶颈。


4
为了限制抛弃变量的范围,同时仍然只调用size()一次,你可以这样写:
for(int i=0, n = itemsList.size(); i < n; i++) {
   // do stuff
}

在选择两个方案时,请按照以下顺序进行优先级排序:

  1. 可读性
  2. 可维护性
  3. 易于理解
  4. 清晰度
  5. 可测试性
  6. 逻辑性
  7. 效率 :-)

2
如果您只是用列表进行阅读,那么应该使用这个。
int length = itemsList.size();            
for(int i=0; i < length; i++)
{
   // do stuff
}

但是如果您从列表中删除元素,则可以使用这种方法。
for(int i=0; i < itemsList.size(); i++)
{
   // do stuff
}

1

第一种方法更有效率,尽管在使用好的编译器时只有微不足道的差别。

除非你每秒要执行数百万次循环,否则不会有任何明显的差异。

原因:

  • 在第一种情况下,循环限制可能会被缓存在寄存器中
  • 在第二种情况下,循环在每次迭代中都会进行额外的内存查找。这是因为循环无法保证大小在每次迭代中不会改变,因此需要不断检查内存值。从技术上讲,还有一个函数调用的开销,尽管一个不错的JIT编译器很可能通过内联完全优化掉这个开销。

0
如果你使用的话
for(int i=0; i < itemsList.size(); i++)
 {
  // do stuff
 }

你总是会调用itemsList.size()方法。所以,如果你把这个值存储在一个变量中,会更快。并且尽量使用final变量;-)

-1

如果您选择第二种方式,itemsList.size() 每次都需要重新计算。

而且如果 itemsList 很大,这可能需要一些时间。


1
大小可能已经预先计算/很容易找到数组。因此开销仅为方法调用的开销。这可能会被JIT编译器内联。 - BaroqueBobcat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接